Actual source code: binv.c
petsc-3.8.0 2017-09-26
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: 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;
30: static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
31: {
32: int rank;
33: PetscErrorCode ierr;
34: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
37: PetscViewerSetUp(viewer);
38: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
39: if (!rank) {
40: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
41: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
42: obinary = (PetscViewer_Binary*)(*outviewer)->data;
43: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
44: } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get subcomm viewer for binary files or sockets unless SubViewer contains the rank 0 process");
45: return(0);
46: }
48: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
49: {
51: PetscErrorCode rank;
54: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
55: if (!rank) {
56: PetscFree((*outviewer)->data);
57: PetscHeaderDestroy(outviewer);
58: }
59: return(0);
60: }
62: #if defined(PETSC_HAVE_MPIIO)
63: /*@C
64: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
66: Not Collective
68: Input Parameter:
69: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
71: Output Parameter:
72: . off - the current offset
74: Level: advanced
76: Fortran Note:
77: This routine is not supported in Fortran.
79: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
81: Concepts: file descriptor^getting
82: Concepts: PetscViewerBinary^accessing file descriptor
84: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
85: @*/
86: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
87: {
88: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
91: *off = vbinary->moff;
92: return(0);
93: }
95: /*@C
96: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
98: Not Collective
100: Input Parameters:
101: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
102: - off - the addition to the offset
104: Level: advanced
106: Fortran Note:
107: This routine is not supported in Fortran.
109: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
111: Concepts: file descriptor^getting
112: Concepts: PetscViewerBinary^accessing file descriptor
114: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
115: @*/
116: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
117: {
118: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
121: vbinary->moff += off;
122: return(0);
123: }
125: /*@C
126: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
128: Not Collective
130: Input Parameter:
131: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
133: Output Parameter:
134: . fdes - file descriptor
136: Level: advanced
138: Fortran Note:
139: This routine is not supported in Fortran.
141: Concepts: file descriptor^getting
142: Concepts: PetscViewerBinary^accessing file descriptor
144: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
145: @*/
146: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
147: {
148: PetscErrorCode ierr;
149: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
152: PetscViewerSetUp(viewer);
153: *fdes = vbinary->mfdes;
154: return(0);
155: }
157: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg)
158: {
159: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
160:
162: *flg = vbinary->usempiio;
163: return(0);
164: }
165: #endif
168: /*@C
169: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
171: Not Collective
173: Input Parameter:
174: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
176: Output Parameter:
177: - flg - PETSC_TRUE if MPI-IO is being used
179: Options Database:
180: -viewer_binary_mpiio : Flag for using MPI-IO
182: Level: advanced
184: Note:
185: If MPI-IO is not available, this function will always return PETSC_FALSE
187: Fortran Note:
188: This routine is not supported in Fortran.
190: Concepts: file descriptor^getting
191: Concepts: PetscViewerBinary^accessing file descriptor
193: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
194: @*/
195: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
196: {
200: *flg = PETSC_FALSE;
201: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
202: return(0);
203: }
205: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
206: {
207: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
210: *fc = vbinary->flowcontrol;
211: return(0);
212: }
214: /*@C
215: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
217: Not Collective
219: Input Parameter:
220: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
222: Output Parameter:
223: . fc - the number of messages
225: Level: advanced
227: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
229: @*/
230: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
231: {
235: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
236: return(0);
237: }
239: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
240: {
241: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
244: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
245: vbinary->flowcontrol = fc;
246: return(0);
247: }
249: /*@C
250: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
252: Not Collective
254: Input Parameter:
255: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
256: - fc - the number of messages, defaults to 256 if this function was not called
258: Level: advanced
260: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
262: @*/
263: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
264: {
268: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
269: return(0);
270: }
272: /*@C
273: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
275: Collective On PetscViewer
277: Input Parameter:
278: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
280: Output Parameter:
281: . fdes - file descriptor
283: Level: advanced
285: Notes:
286: For writable binary PetscViewers, the descriptor will only be valid for the
287: first processor in the communicator that shares the PetscViewer. For readable
288: files it will only be valid on nodes that have the file. If node 0 does not
289: have the file it generates an error even if another node does have the file.
291: Fortran Note:
292: This routine is not supported in Fortran.
294: Developer Notes: This must be called on all processes because Dave May changed
295: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
298: Concepts: file descriptor^getting
299: Concepts: PetscViewerBinary^accessing file descriptor
301: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
302: @*/
303: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
304: {
305: PetscErrorCode ierr;
306: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
309: PetscViewerSetUp(viewer);
310: *fdes = vbinary->fdes;
311: return(0);
312: }
314: /*@
315: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
317: Not Collective
319: Input Paramter:
320: . viewer - PetscViewer context, obtained from PetscViewerCreate()
322: Options Database Key:
323: . -viewer_binary_skip_info
325: Level: advanced
327: Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
328: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
329: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
331: The .info contains meta information about the data in the binary file, for example the block size if it was
332: set for a vector or matrix.
334: Concepts: PetscViewerBinary^accessing info file
336: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
337: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
338: @*/
339: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
340: {
341: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
344: vbinary->skipinfo = PETSC_TRUE;
345: return(0);
346: }
348: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
349: {
350: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
353: vbinary->skipinfo = skip;
354: return(0);
355: }
357: /*@
358: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
360: Not Collective
362: Input Paramter:
363: . viewer - PetscViewer context, obtained from PetscViewerCreate()
365: Options Database Key:
366: . -viewer_binary_skip_info
368: Level: advanced
370: Concepts: PetscViewerBinary^accessing info file
372: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
373: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
374: @*/
375: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
376: {
380: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
381: return(0);
382: }
384: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
385: {
386: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
389: *skip = vbinary->skipinfo;
390: return(0);
391: }
393: /*@
394: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
396: Not Collective
398: Input Parameter:
399: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
401: Output Parameter:
402: . skip - PETSC_TRUE implies the .info file was not generated
404: Level: advanced
406: Notes: This must be called after PetscViewerSetType()
408: Concepts: PetscViewerBinary^accessing info file
410: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
411: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
412: @*/
413: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
414: {
418: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
419: return(0);
420: }
422: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
423: {
424: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
427: vbinary->skipoptions = skip;
428: return(0);
429: }
431: /*@
432: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
434: Not Collective
436: Input Parameters:
437: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
438: - skip - PETSC_TRUE means do not use
440: Options Database Key:
441: . -viewer_binary_skip_options
443: Level: advanced
445: Notes: This must be called after PetscViewerSetType()
447: Concepts: PetscViewerBinary^accessing info file
449: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
450: PetscViewerBinaryGetSkipOptions()
451: @*/
452: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
453: {
457: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
458: return(0);
459: }
461: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
462: {
463: PetscViewer_Binary *vbinary;
467: vbinary = (PetscViewer_Binary*)viewer->data;
468: *skip = vbinary->skipoptions;
469: return(0);
470: }
472: /*@
473: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
475: Not Collective
477: Input Parameter:
478: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
480: Output Parameter:
481: . skip - PETSC_TRUE means do not use
483: Level: advanced
485: Notes: This must be called after PetscViewerSetType()
487: Concepts: PetscViewerBinary^accessing info file
489: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
490: PetscViewerBinarySetSkipOptions()
491: @*/
492: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
493: {
497: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
498: return(0);
499: }
501: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
502: {
503: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
506: vbinary->skipheader = skip;
507: return(0);
508: }
510: /*@
511: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
513: Not Collective
515: Input Parameters:
516: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
517: - skip - PETSC_TRUE means do not write header
519: Options Database Key:
520: . -viewer_binary_skip_header
522: Level: advanced
524: Notes: This must be called after PetscViewerSetType()
526: Can ONLY be called on a binary viewer
528: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
529: PetscViewerBinaryGetSkipHeader()
530: @*/
531: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
532: {
536: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
537: return(0);
538: }
540: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
541: {
542: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
545: *skip = vbinary->skipheader;
546: return(0);
547: }
549: /*@
550: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
552: Not Collective
554: Input Parameter:
555: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
557: Output Parameter:
558: . skip - PETSC_TRUE means do not write header
560: Level: advanced
562: Notes: This must be called after PetscViewerSetType()
564: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
566: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
567: PetscViewerBinarySetSkipHeader()
568: @*/
569: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
570: {
574: *skip = PETSC_FALSE;
575: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
576: return(0);
577: }
579: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
580: {
581: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
582: PetscErrorCode ierr;
583: MPI_Comm comm;
586: PetscViewerSetUp(viewer);
587: *file = vbinary->fdes_info;
588: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
589: vbinary->matlabheaderwritten = PETSC_TRUE;
590: PetscObjectGetComm((PetscObject)viewer,&comm);
591: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
592: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
593: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
594: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
595: }
596: return(0);
597: }
599: /*@C
600: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
601: info file associated with a binary file.
603: Not Collective
605: Input Parameter:
606: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
608: Output Parameter:
609: . file - file pointer Always returns NULL if not a binary viewer
611: Level: advanced
613: Notes:
614: For writable binary PetscViewers, the descriptor will only be valid for the
615: first processor in the communicator that shares the PetscViewer.
617: Fortran Note:
618: This routine is not supported in Fortran.
620: Concepts: PetscViewerBinary^accessing info file
622: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
623: @*/
624: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
625: {
629: *file = NULL;
630: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
631: return(0);
632: }
634: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
635: {
636: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
637: PetscErrorCode ierr;
638: PetscMPIInt rank;
639: int err;
642: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
643: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
644: close(vbinary->fdes);
645: if (!rank && vbinary->storecompressed) {
646: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
647: FILE *fp;
648: /* compress the file */
649: PetscStrcpy(par,"gzip -f ");
650: PetscStrcat(par,vbinary->filename);
651: #if defined(PETSC_HAVE_POPEN)
652: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
653: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
654: PetscPClose(PETSC_COMM_SELF,fp,NULL);
655: #else
656: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
657: #endif
658: }
659: }
660: if (vbinary->fdes_info) {
661: err = fclose(vbinary->fdes_info);
662: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
663: }
664: return(0);
665: }
667: #if defined(PETSC_HAVE_MPIIO)
668: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
669: {
670: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
671: int err;
672: PetscErrorCode ierr;
675: if (vbinary->mfdes) {
676: MPI_File_close(&vbinary->mfdes);
677: }
678: if (vbinary->fdes_info) {
679: err = fclose(vbinary->fdes_info);
680: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
681: }
682: return(0);
683: }
684: #endif
686: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
687: {
688: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
689: PetscErrorCode ierr;
692: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
693: MPI_Comm comm;
694: FILE *info;
696: PetscObjectGetComm((PetscObject)v,&comm);
697: PetscViewerBinaryGetInfoPointer(v,&info);
698: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
699: PetscFPrintf(comm,info,"#$$ close(fd);\n");
700: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
701: }
702: #if defined(PETSC_HAVE_MPIIO)
703: if (vbinary->usempiio) {
704: PetscViewerFileClose_BinaryMPIIO(v);
705: } else {
706: #endif
707: PetscViewerFileClose_Binary(v);
708: #if defined(PETSC_HAVE_MPIIO)
709: }
710: #endif
711: if (vbinary->filename) { PetscFree(vbinary->filename); }
712: PetscFree(vbinary);
713: return(0);
714: }
716: /*@C
717: PetscViewerBinaryOpen - Opens a file for binary input/output.
719: Collective on MPI_Comm
721: Input Parameters:
722: + comm - MPI communicator
723: . name - name of file
724: - type - type of file
725: $ FILE_MODE_WRITE - create new file for binary output
726: $ FILE_MODE_READ - open existing file for binary input
727: $ FILE_MODE_APPEND - open existing file for binary output
729: Output Parameter:
730: . binv - PetscViewer for binary input/output to use with the specified file
732: Options Database Keys:
733: + -viewer_binary_filename <name>
734: . -viewer_binary_skip_info
735: . -viewer_binary_skip_options
736: . -viewer_binary_skip_header
737: - -viewer_binary_mpiio
739: Level: beginner
741: Note:
742: This PetscViewer should be destroyed with PetscViewerDestroy().
744: For reading files, the filename may begin with ftp:// or http:// and/or
745: end with .gz; in this case file is brought over and uncompressed.
747: For creating files, if the file name ends with .gz it is automatically
748: compressed when closed.
750: For writing files it only opens the file on processor 0 in the communicator.
751: For readable files it opens the file on all nodes that have the file. If
752: node 0 does not have the file it generates an error even if other nodes
753: do have the file.
755: Concepts: binary files
756: Concepts: PetscViewerBinary^creating
757: Concepts: gzip
758: Concepts: accessing remote file
759: Concepts: remote file
761: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
762: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
763: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
764: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
765: @*/
766: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
767: {
771: PetscViewerCreate(comm,binv);
772: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
773: PetscViewerFileSetMode(*binv,type);
774: PetscViewerFileSetName(*binv,name);
775: PetscViewerSetFromOptions(*binv);
776: return(0);
777: }
779: #if defined(PETSC_HAVE_MPIIO)
780: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
781: {
782: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
783: PetscErrorCode ierr;
784: MPI_Datatype mdtype;
785: PetscMPIInt cnt;
786: MPI_Status status;
787: MPI_Aint ul,dsize;
790: PetscMPIIntCast(num,&cnt);
791: PetscDataTypeToMPIDataType(dtype,&mdtype);
792: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
793: if (write) {
794: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
795: } else {
796: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
797: }
798: MPI_Type_get_extent(mdtype,&ul,&dsize);
800: vbinary->moff += dsize*cnt;
801: if (count) *count = num;
802: return(0);
803: }
804: #endif
806: /*@C
807: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
809: Collective on MPI_Comm
811: Input Parameters:
812: + viewer - the binary viewer
813: . data - location of the data to be written
814: . num - number of items of data to read
815: - dtype - type of data to read
817: Output Parameters:
818: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
820: Level: beginner
822: Concepts: binary files
824: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
826: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
827: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
828: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
829: @*/
830: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
831: {
832: PetscErrorCode ierr;
833: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
835: PetscViewerSetUp(viewer);
836: #if defined(PETSC_HAVE_MPIIO)
837: if (vbinary->usempiio) {
838: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
839: } else {
840: #endif
841: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
842: if (count) *count = num;
843: #if defined(PETSC_HAVE_MPIIO)
844: }
845: #endif
846: return(0);
847: }
849: /*@C
850: PetscViewerBinaryWrite - writes to a binary file, only from the first process
852: Collective on MPI_Comm
854: Input Parameters:
855: + viewer - the binary viewer
856: . data - location of data
857: . count - number of items of data to write
858: . dtype - type of data to write
859: - istemp - data may be overwritten
861: Level: beginner
863: Notes: because byte-swapping may be done on the values in data it cannot be declared const
865: Concepts: binary files
867: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
868: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
869: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
870: @*/
871: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
872: {
873: PetscErrorCode ierr;
874: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
877: PetscViewerSetUp(viewer);
878: #if defined(PETSC_HAVE_MPIIO)
879: if (vbinary->usempiio) {
880: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
881: } else {
882: #endif
883: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
884: #if defined(PETSC_HAVE_MPIIO)
885: }
886: #endif
887: return(0);
888: }
890: /*@C
891: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
893: Collective on MPI_Comm
895: Input Parameters:
896: + viewer - the binary viewer
897: - data - location of the array of strings
900: Level: intermediate
902: Concepts: binary files
904: Notes: array of strings is null terminated
906: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
907: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
908: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
909: @*/
910: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
911: {
913: PetscInt i,n = 0,*sizes;
915: PetscViewerSetUp(viewer);
916: /* count number of strings */
917: while (data[n++]) ;
918: n--;
919: PetscMalloc1(n+1,&sizes);
920: sizes[0] = n;
921: for (i=0; i<n; i++) {
922: size_t tmp;
923: PetscStrlen(data[i],&tmp);
924: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
925: }
926: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
927: for (i=0; i<n; i++) {
928: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
929: }
930: PetscFree(sizes);
931: return(0);
932: }
934: /*@C
935: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
937: Collective on MPI_Comm
939: Input Parameter:
940: . viewer - the binary viewer
942: Output Parameter:
943: . data - location of the array of strings
945: Level: intermediate
947: Concepts: binary files
949: Notes: array of strings is null terminated
951: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
952: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
953: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
954: @*/
955: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
956: {
958: PetscInt i,n,*sizes,N = 0;
960: PetscViewerSetUp(viewer);
961: /* count number of strings */
962: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
963: PetscMalloc1(n,&sizes);
964: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
965: for (i=0; i<n; i++) N += sizes[i];
966: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
967: (*data)[0] = (char*)((*data) + n + 1);
968: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
969: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
971: (*data)[n] = 0;
973: PetscFree(sizes);
974: return(0);
975: }
977: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
978: {
979: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
982: *name = vbinary->filename;
983: return(0);
984: }
986: /*@C
987: PetscViewerFileGetMode - Gets the type of file to be open
989: Not Collective
991: Input Parameter:
992: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
994: Output Parameter:
995: . type - type of file
996: $ FILE_MODE_WRITE - create new file for binary output
997: $ FILE_MODE_READ - open existing file for binary input
998: $ FILE_MODE_APPEND - open existing file for binary output
1000: Level: advanced
1002: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1004: @*/
1005: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1006: {
1012: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1013: return(0);
1014: }
1016: /*@
1017: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1018: before PetscViewerFileSetName()
1020: Logically Collective on PetscViewer
1022: Input Parameters:
1023: + viewer - the PetscViewer; must be a binary
1024: - flg - PETSC_TRUE means MPI-IO will be used
1026: Options Database:
1027: -viewer_binary_mpiio : Flag for using MPI-IO
1029: Level: advanced
1031: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1032: PetscViewerBinaryGetUseMPIIO()
1034: @*/
1035: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1036: {
1041: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1042: return(0);
1043: }
1045: /*@C
1046: PetscViewerFileSetMode - Sets the type of file to be open
1048: Logically Collective on PetscViewer
1050: Input Parameters:
1051: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1052: - type - type of file
1053: $ FILE_MODE_WRITE - create new file for binary output
1054: $ FILE_MODE_READ - open existing file for binary input
1055: $ FILE_MODE_APPEND - open existing file for binary output
1057: Level: advanced
1059: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1061: @*/
1062: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1063: {
1069: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1070: return(0);
1071: }
1073: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1074: {
1075: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1078: *type = vbinary->btype;
1079: return(0);
1080: }
1082: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1083: {
1084: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1087: vbinary->btype = type;
1088: return(0);
1089: }
1091: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1092: {
1093: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1094: PetscErrorCode ierr;
1097: if (vbinary->filename) { PetscFree(vbinary->filename); }
1098: PetscStrallocpy(name,&vbinary->filename);
1099: return(0);
1100: }
1101: /*
1102: Actually opens the file
1103: */
1104: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1105: {
1106: PetscMPIInt rank;
1107: PetscErrorCode ierr;
1108: size_t len;
1109: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1110: const char *fname;
1111: char bname[PETSC_MAX_PATH_LEN],*gz;
1112: PetscBool found;
1113: PetscFileMode type = vbinary->btype;
1116: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1117: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1118: PetscViewerFileClose_Binary(viewer);
1120: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1122: /* if ends in .gz strip that off and note user wants file compressed */
1123: vbinary->storecompressed = PETSC_FALSE;
1124: if (!rank && type == FILE_MODE_WRITE) {
1125: /* remove .gz if it ends library name */
1126: PetscStrstr(vbinary->filename,".gz",&gz);
1127: if (gz) {
1128: PetscStrlen(gz,&len);
1129: if (len == 3) {
1130: *gz = 0;
1131: vbinary->storecompressed = PETSC_TRUE;
1132: }
1133: }
1134: }
1136: /* only first processor opens file if writeable */
1137: if (!rank || type == FILE_MODE_READ) {
1139: if (type == FILE_MODE_READ) {
1140: /* possibly get the file from remote site or compressed file */
1141: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1142: fname = bname;
1143: if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1144: else if (!found) {
1145: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
1146: fname = 0;
1147: }
1148: } else fname = vbinary->filename;
1150: #if defined(PETSC_HAVE_O_BINARY)
1151: if (type == FILE_MODE_WRITE) {
1152: 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);
1153: } else if (type == FILE_MODE_READ && fname) {
1154: 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);
1155: } else if (type == FILE_MODE_APPEND) {
1156: 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);
1157: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1158: #else
1159: if (type == FILE_MODE_WRITE) {
1160: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1161: } else if (type == FILE_MODE_READ && fname) {
1162: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1163: } else if (type == FILE_MODE_APPEND) {
1164: 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);
1165: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1166: #endif
1167: } else vbinary->fdes = -1;
1169: /*
1170: try to open info file: all processors open this file if read only
1171: */
1172: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1173: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1175: PetscStrcpy(infoname,vbinary->filename);
1176: /* remove .gz if it ends library name */
1177: PetscStrstr(infoname,".gz",&gz);
1178: if (gz) {
1179: PetscStrlen(gz,&len);
1180: if (len == 3) *gz = 0;
1181: }
1183: PetscStrcat(infoname,".info");
1184: PetscFixFilename(infoname,iname);
1185: if (type == FILE_MODE_READ) {
1186: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1187: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1188: } else {
1189: vbinary->fdes_info = fopen(infoname,"w");
1190: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1191: }
1192: }
1193: #if defined(PETSC_USE_LOG)
1194: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1195: #endif
1196: return(0);
1197: }
1199: #if defined(PETSC_HAVE_MPIIO)
1200: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1201: {
1202: PetscMPIInt rank;
1203: PetscErrorCode ierr;
1204: size_t len;
1205: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1206: char *gz;
1207: PetscBool found;
1208: PetscFileMode type = vbinary->btype;
1211: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1212: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1213: PetscViewerFileClose_BinaryMPIIO(viewer);
1215: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1217: vbinary->storecompressed = PETSC_FALSE;
1219: /* only first processor opens file if writeable */
1220: if (type == FILE_MODE_READ) {
1221: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1222: } else if (type == FILE_MODE_WRITE) {
1223: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1224: }
1226: /*
1227: try to open info file: all processors open this file if read only
1229: Below is identical code to the code for Binary above, should be put in separate routine
1230: */
1231: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1232: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1234: PetscStrcpy(infoname,vbinary->filename);
1235: /* remove .gz if it ends library name */
1236: PetscStrstr(infoname,".gz",&gz);
1237: if (gz) {
1238: PetscStrlen(gz,&len);
1239: if (len == 3) *gz = 0;
1240: }
1242: PetscStrcat(infoname,".info");
1243: PetscFixFilename(infoname,iname);
1244: if (type == FILE_MODE_READ) {
1245: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1246: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1247: } else {
1248: vbinary->fdes_info = fopen(infoname,"w");
1249: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1250: }
1251: }
1252: #if defined(PETSC_USE_LOG)
1253: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1254: #endif
1255: return(0);
1256: }
1258: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1259: {
1260: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1262: vbinary->usempiio = flg;
1263: return(0);
1264: }
1265: #endif
1267: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1268: {
1269: PetscErrorCode ierr;
1270: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1273: if (binary->filename) {
1274: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1275: }
1276: return(0);
1277: }
1279: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1280: {
1281: PetscErrorCode ierr;
1282: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1285: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1286:
1287: #if defined(PETSC_HAVE_MPIIO)
1288: if (binary->usempiio) {
1289: PetscViewerFileSetUp_BinaryMPIIO(v);
1290: } else {
1291: #endif
1292: PetscViewerFileSetUp_Binary(v);
1293: #if defined(PETSC_HAVE_MPIIO)
1294: }
1295: #endif
1296: return(0);
1297: }
1299: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1300: {
1301: PetscErrorCode ierr;
1302: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1303: char defaultname[PETSC_MAX_PATH_LEN];
1304: PetscBool flg;
1307: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1308: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1309: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1310: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1311: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1312: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1313: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1314: #if defined(PETSC_HAVE_MPIIO)
1315: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1316: #elif defined(PETSC_HAVE_MPIUNI)
1317: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1318: #endif
1319: PetscOptionsTail();
1320: binary->setfromoptionscalled = PETSC_TRUE;
1321: return(0);
1322: }
1324: /*MC
1325: PETSCVIEWERBINARY - A viewer that saves to binary files
1328: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1329: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1330: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1331: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1333: Level: beginner
1335: M*/
1337: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1338: {
1339: PetscErrorCode ierr;
1340: PetscViewer_Binary *vbinary;
1343: PetscNewLog(v,&vbinary);
1344: v->data = (void*)vbinary;
1345: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1346: v->ops->destroy = PetscViewerDestroy_Binary;
1347: v->ops->view = PetscViewerView_Binary;
1348: v->ops->setup = PetscViewerSetUp_Binary;
1349: v->ops->flush = NULL;
1350: vbinary->fdes_info = 0;
1351: vbinary->fdes = 0;
1352: vbinary->skipinfo = PETSC_FALSE;
1353: vbinary->skipoptions = PETSC_TRUE;
1354: vbinary->skipheader = PETSC_FALSE;
1355: vbinary->setfromoptionscalled = PETSC_FALSE;
1356: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1357: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1358: v->ops->read = PetscViewerBinaryRead;
1359: vbinary->btype = (PetscFileMode) -1;
1360: vbinary->storecompressed = PETSC_FALSE;
1361: vbinary->filename = 0;
1362: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1364: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1365: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1366: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1367: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1368: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1369: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1370: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1371: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1372: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1373: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1374: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1375: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1376: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1377: #if defined(PETSC_HAVE_MPIIO)
1378: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1379: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1380: #endif
1381: return(0);
1382: }
1384: /* ---------------------------------------------------------------------*/
1385: /*
1386: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1387: is attached to a communicator, in this case the attribute is a PetscViewer.
1388: */
1389: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1391: /*@C
1392: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1393: in a communicator.
1395: Collective on MPI_Comm
1397: Input Parameter:
1398: . comm - the MPI communicator to share the binary PetscViewer
1400: Level: intermediate
1402: Options Database Keys:
1403: + -viewer_binary_filename <name>
1404: . -viewer_binary_skip_info
1405: . -viewer_binary_skip_options
1406: . -viewer_binary_skip_header
1407: - -viewer_binary_mpiio
1409: Environmental variables:
1410: - PETSC_VIEWER_BINARY_FILENAME
1412: Notes:
1413: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1414: an error code. The binary PetscViewer is usually used in the form
1415: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1417: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1418: PetscViewerDestroy()
1419: @*/
1420: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1421: {
1423: PetscBool flg;
1424: PetscViewer viewer;
1425: char fname[PETSC_MAX_PATH_LEN];
1426: MPI_Comm ncomm;
1429: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1430: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1431: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1432: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1433: }
1434: MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1435: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1436: if (!flg) { /* PetscViewer not yet created */
1437: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1438: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1439: if (!flg) {
1440: PetscStrcpy(fname,"binaryoutput");
1441: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1442: }
1443: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1444: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1445: PetscObjectRegisterDestroy((PetscObject)viewer);
1446: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1447: MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1448: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1449: }
1450: PetscCommDestroy(&ncomm);
1451: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1452: PetscFunctionReturn(viewer);
1453: }