Actual source code: binv.c
petsc-3.5.4 2015-05-23
2: #include <petsc-private/viewerimpl.h> /*I "petscviewer.h" I*/
3: #include <fcntl.h>
4: #if defined(PETSC_HAVE_UNISTD_H)
5: #include <unistd.h>
6: #endif
7: #if defined(PETSC_HAVE_IO_H)
8: #include <io.h>
9: #endif
11: typedef struct {
12: int fdes; /* file descriptor, ignored if using MPI IO */
13: #if defined(PETSC_HAVE_MPIIO)
14: PetscBool MPIIO;
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: } PetscViewer_Binary;
31: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
32: {
33: int rank;
34: PetscErrorCode ierr;
35: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
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 singleton viewer for binary files or sockets");
45: return(0);
46: }
50: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
51: {
53: PetscErrorCode rank;
56: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
57: if (!rank) {
58: PetscFree((*outviewer)->data);
59: PetscHeaderDestroy(outviewer);
60: }
61: return(0);
62: }
64: #if defined(PETSC_HAVE_MPIIO)
67: /*@C
68: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
70: Not Collective
72: Input Parameter:
73: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
75: Output Parameter:
76: . off - the current offset
78: Level: advanced
80: Fortran Note:
81: This routine is not supported in Fortran.
83: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
85: Concepts: file descriptor^getting
86: Concepts: PetscViewerBinary^accessing file descriptor
88: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
89: @*/
90: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
91: {
92: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
95: *off = vbinary->moff;
96: return(0);
97: }
101: /*@C
102: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
104: Not Collective
106: Input Parameters:
107: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
108: - off - the addition to the offset
110: Level: advanced
112: Fortran Note:
113: This routine is not supported in Fortran.
115: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
117: Concepts: file descriptor^getting
118: Concepts: PetscViewerBinary^accessing file descriptor
120: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
121: @*/
122: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
123: {
124: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
127: vbinary->moff += off;
128: return(0);
129: }
133: /*@C
134: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
136: Not Collective
138: Input Parameter:
139: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
141: Output Parameter:
142: . fdes - file descriptor
144: Level: advanced
146: Fortran Note:
147: This routine is not supported in Fortran.
149: Concepts: file descriptor^getting
150: Concepts: PetscViewerBinary^accessing file descriptor
152: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
153: @*/
154: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
155: {
156: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
159: *fdes = vbinary->mfdes;
160: return(0);
161: }
165: /*@C
166: PetscViewerBinaryGetMPIIO - Returns PETSC_TRUE if the binary viewer is an MPI viewer.
168: Not Collective
170: Input Parameter:
171: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
173: Output Parameter:
174: - flg - PETSC_TRUE if MPI IO is being used
176: Options Database:
177: -viewer_binary_mpiio : Flag for using MPI-IO
179: Level: advanced
181: Fortran Note:
182: This routine is not supported in Fortran.
184: Concepts: file descriptor^getting
185: Concepts: PetscViewerBinary^accessing file descriptor
187: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
188: @*/
189: PetscErrorCode PetscViewerBinaryGetMPIIO(PetscViewer viewer,PetscBool *flg)
190: {
191: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
194: *flg = vbinary->MPIIO;
195: return(0);
196: }
197: #endif
201: PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
202: {
203: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
206: *fc = vbinary->flowcontrol;
207: return(0);
208: }
212: /*@C
213: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
215: Not Collective
217: Input Parameter:
218: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
220: Output Parameter:
221: . fc - the number of messages
223: Level: advanced
225: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
227: @*/
228: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
229: {
230: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
231: PetscErrorCode ierr;
234: *fc = vbinary->flowcontrol;
235: PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
236: return(0);
237: }
241: PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
242: {
243: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
246: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
247: vbinary->flowcontrol = fc;
248: return(0);
249: }
253: /*@C
254: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
256: Not Collective
258: Input Parameter:
259: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
260: - fc - the number of messages, defaults to 256 if this function was not called
262: Level: advanced
264: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
266: @*/
267: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
268: {
272: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
273: return(0);
274: }
278: /*@C
279: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
281: Not Collective
283: Input Parameter:
284: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
286: Output Parameter:
287: . fdes - file descriptor
289: Level: advanced
291: Notes:
292: For writable binary PetscViewers, the descriptor will only be valid for the
293: first processor in the communicator that shares the PetscViewer. For readable
294: files it will only be valid on nodes that have the file. If node 0 does not
295: have the file it generates an error even if another node does have the file.
297: Fortran Note:
298: This routine is not supported in Fortran.
300: Concepts: file descriptor^getting
301: Concepts: PetscViewerBinary^accessing file descriptor
303: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
304: @*/
305: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
306: {
307: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
310: *fdes = vbinary->fdes;
311: return(0);
312: }
316: /*@
317: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
319: Not Collective
321: Input Paramter:
322: . viewer - PetscViewer context, obtained from PetscViewerCreate()
324: Options Database Key:
325: . -viewer_binary_skip_info
327: Level: advanced
329: Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then
330: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
331: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().
333: The .info contains meta information about the data in the binary file, for example the block size if it was
334: set for a vector or matrix.
336: Concepts: PetscViewerBinary^accessing info file
338: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
339: PetscViewerBinaryGetSkipOptions()
340: @*/
341: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
342: {
343: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
346: vbinary->skipinfo = PETSC_TRUE;
347: return(0);
348: }
352: /*@
353: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
355: Not Collective
357: Input Parameters:
358: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
359: - skip - PETSC_TRUE means do not use
361: Options Database Key:
362: . -viewer_binary_skip_options
364: Level: advanced
366: Notes: This must be called after PetscViewerSetType()
368: Concepts: PetscViewerBinary^accessing info file
370: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
371: PetscViewerBinaryGetSkipOptions()
372: @*/
373: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
374: {
375: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
378: vbinary->skipoptions = skip;
379: return(0);
380: }
384: /*@
385: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
387: Not Collective
389: Input Parameter:
390: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
392: Output Parameter:
393: . skip - PETSC_TRUE means do not use
395: Level: advanced
397: Notes: This must be called after PetscViewerSetType()
399: Concepts: PetscViewerBinary^accessing info file
401: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
402: PetscViewerBinarySetSkipOptions()
403: @*/
404: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
405: {
406: PetscViewer_Binary *vbinary;
410: vbinary = (PetscViewer_Binary*)viewer->data;
411: *skip = vbinary->skipoptions;
412: return(0);
413: }
417: PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
418: {
419: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
422: vbinary->skipheader = skip;
423: return(0);
424: }
428: /*@
429: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
431: Not Collective
433: Input Parameters:
434: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
435: - skip - PETSC_TRUE means do not write header
437: Options Database Key:
438: . -viewer_binary_skip_header
440: Level: advanced
442: Notes: This must be called after PetscViewerSetType()
444: Can ONLY be called on a binary viewer
446: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
447: PetscViewerBinaryGetSkipHeader()
448: @*/
449: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
450: {
454: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
455: return(0);
456: }
460: PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
461: {
462: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
465: *skip = vbinary->skipheader;
466: return(0);
467: }
471: /*@
472: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
474: Not Collective
476: Input Parameter:
477: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
479: Output Parameter:
480: . skip - PETSC_TRUE means do not write header
482: Level: advanced
484: Notes: This must be called after PetscViewerSetType()
486: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
488: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
489: PetscViewerBinarySetSkipHeader()
490: @*/
491: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
492: {
496: *skip = PETSC_FALSE;
497: PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
498: return(0);
499: }
503: PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
504: {
505: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
506: PetscErrorCode ierr;
507: MPI_Comm comm;
510: *file = vbinary->fdes_info;
511: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
512: vbinary->matlabheaderwritten = PETSC_TRUE;
513: PetscObjectGetComm((PetscObject)viewer,&comm);
514: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
515: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
516: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
517: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
518: }
519: return(0);
520: }
524: /*@C
525: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
526: info file associated with a binary file.
528: Not Collective
530: Input Parameter:
531: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
533: Output Parameter:
534: . file - file pointer Always returns NULL if not a binary viewer
536: Level: advanced
538: Notes:
539: For writable binary PetscViewers, the descriptor will only be valid for the
540: first processor in the communicator that shares the PetscViewer.
542: Fortran Note:
543: This routine is not supported in Fortran.
545: Concepts: PetscViewerBinary^accessing info file
547: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
548: @*/
549: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
550: {
554: *file = NULL;
555: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
556: return(0);
557: }
561: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
562: {
563: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
564: PetscErrorCode ierr;
565: PetscMPIInt rank;
566: int err;
569: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
570: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
571: close(vbinary->fdes);
572: if (!rank && vbinary->storecompressed) {
573: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
574: FILE *fp;
575: /* compress the file */
576: PetscStrcpy(par,"gzip -f ");
577: PetscStrcat(par,vbinary->filename);
578: #if defined(PETSC_HAVE_POPEN)
579: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
580: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
581: PetscPClose(PETSC_COMM_SELF,fp,NULL);
582: #else
583: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
584: #endif
585: }
586: }
587: if (vbinary->fdes_info) {
588: err = fclose(vbinary->fdes_info);
589: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
590: }
591: PetscFree(vbinary->filename);
592: return(0);
593: }
597: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
598: {
599: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
600: PetscErrorCode ierr;
603: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
604: MPI_Comm comm;
605: FILE *info;
607: PetscObjectGetComm((PetscObject)v,&comm);
608: PetscViewerBinaryGetInfoPointer(v,&info);
609: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
610: PetscFPrintf(comm,info,"#$$ close(fd);\n");
611: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
612: }
613: PetscViewerFileClose_Binary(v);
614: PetscFree(vbinary);
615: return(0);
616: }
618: #if defined(PETSC_HAVE_MPIIO)
621: static PetscErrorCode PetscViewerFileClose_MPIIO(PetscViewer v)
622: {
623: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
624: int err;
625: PetscErrorCode ierr;
628: if (vbinary->mfdes) {
629: MPI_File_close(&vbinary->mfdes);
630: }
631: if (vbinary->fdes_info) {
632: err = fclose(vbinary->fdes_info);
633: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
634: }
635: PetscFree(vbinary->filename);
636: return(0);
637: }
642: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
643: {
644: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
645: PetscErrorCode ierr;
648: PetscViewerFileClose_MPIIO(v);
649: PetscFree(vbinary);
650: return(0);
651: }
652: #endif
656: /*@C
657: PetscViewerBinaryOpen - Opens a file for binary input/output.
659: Collective on MPI_Comm
661: Input Parameters:
662: + comm - MPI communicator
663: . name - name of file
664: - type - type of file
665: $ FILE_MODE_WRITE - create new file for binary output
666: $ FILE_MODE_READ - open existing file for binary input
667: $ FILE_MODE_APPEND - open existing file for binary output
669: Output Parameter:
670: . binv - PetscViewer for binary input/output to use with the specified file
672: Options Database Keys:
673: + -viewer_binary_skip_info
674: . -viewer_binary_skip_options
675: - -viewer_binary_skip_header
677: Level: beginner
679: Note:
680: This PetscViewer should be destroyed with PetscViewerDestroy().
682: For reading files, the filename may begin with ftp:// or http:// and/or
683: end with .gz; in this case file is brought over and uncompressed.
685: For creating files, if the file name ends with .gz it is automatically
686: compressed when closed.
688: For writing files it only opens the file on processor 0 in the communicator.
689: For readable files it opens the file on all nodes that have the file. If
690: node 0 does not have the file it generates an error even if other nodes
691: do have the file.
693: Concepts: binary files
694: Concepts: PetscViewerBinary^creating
695: Concepts: gzip
696: Concepts: accessing remote file
697: Concepts: remote file
699: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
700: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
701: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
702: @*/
703: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
704: {
708: PetscViewerCreate(comm,binv);
709: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
710: PetscViewerFileSetMode(*binv,type);
711: PetscViewerFileSetName(*binv,name);
712: return(0);
713: }
715: #if defined(PETSC_HAVE_MPIIO)
718: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool write)
719: {
720: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
721: PetscErrorCode ierr;
722: MPI_Datatype mdtype;
723: PetscMPIInt cnt;
724: MPI_Status status;
725: MPI_Aint ul,dsize;
728: PetscMPIIntCast(count,&cnt);
729: PetscDataTypeToMPIDataType(dtype,&mdtype);
730: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
731: if (write) {
732: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
733: } else {
734: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
735: }
736: MPI_Type_get_extent(mdtype,&ul,&dsize);
738: vbinary->moff += dsize*cnt;
739: return(0);
740: }
741: #endif
745: /*@C
746: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
748: Collective on MPI_Comm
750: Input Parameters:
751: + viewer - the binary viewer
752: . data - location to write the data
753: . count - number of items of data to read
754: - datatype - type of data to read
756: Level: beginner
758: Concepts: binary files
760: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
761: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
762: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
763: @*/
764: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
765: {
766: PetscErrorCode ierr;
767: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
769: #if defined(PETSC_HAVE_MPIIO)
770: if (vbinary->MPIIO) {
771: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
772: } else {
773: #endif
774: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);
775: #if defined(PETSC_HAVE_MPIIO)
776: }
777: #endif
778: return(0);
779: }
784: /*@C
785: PetscViewerBinaryWrite - writes to a binary file, only from the first process
787: Collective on MPI_Comm
789: Input Parameters:
790: + viewer - the binary viewer
791: . data - location of data
792: . count - number of items of data to read
793: . dtype - type of data to read
794: - istemp - data may be overwritten
796: Level: beginner
798: Notes: because byte-swapping may be done on the values in data it cannot be declared const
800: Concepts: binary files
802: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
803: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
804: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
805: @*/
806: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
807: {
808: PetscErrorCode ierr;
809: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
812: #if defined(PETSC_HAVE_MPIIO)
813: if (vbinary->MPIIO) {
814: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
815: } else {
816: #endif
817: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
818: #if defined(PETSC_HAVE_MPIIO)
819: }
820: #endif
821: return(0);
822: }
826: /*@C
827: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
829: Collective on MPI_Comm
831: Input Parameters:
832: + viewer - the binary viewer
833: - data - location of the array of strings
836: Level: intermediate
838: Concepts: binary files
840: Notes: array of strings is null terminated
842: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
843: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
844: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
845: @*/
846: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
847: {
849: PetscInt i,n = 0,*sizes;
851: /* count number of strings */
852: while (data[n++]) ;
853: n--;
854: PetscMalloc1((n+1),&sizes);
855: sizes[0] = n;
856: for (i=0; i<n; i++) {
857: size_t tmp;
858: PetscStrlen(data[i],&tmp);
859: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
860: }
861: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
862: for (i=0; i<n; i++) {
863: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
864: }
865: PetscFree(sizes);
866: return(0);
867: }
869: /*@C
870: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
872: Collective on MPI_Comm
874: Input Parameter:
875: . viewer - the binary viewer
877: Output Parameter:
878: . data - location of the array of strings
880: Level: intermediate
882: Concepts: binary files
884: Notes: array of strings is null terminated
886: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
887: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
888: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
889: @*/
890: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
891: {
893: PetscInt i,n,*sizes,N = 0;
895: /* count number of strings */
896: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
897: PetscMalloc1(n,&sizes);
898: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
899: for (i=0; i<n; i++) N += sizes[i];
900: PetscMalloc1((n+1)*sizeof(char*) + N,data);
901: (*data)[0] = (char*)((*data) + n + 1);
902: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
903: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
905: (*data)[n] = 0;
907: PetscFree(sizes);
908: return(0);
909: }
913: PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
914: {
915: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
918: *name = vbinary->filename;
919: return(0);
920: }
924: /*@C
925: PetscViewerFileGetMode - Gets the type of file to be open
927: Not Collective
929: Input Parameter:
930: . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer
932: Output Parameter:
933: . type - type of file
934: $ FILE_MODE_WRITE - create new file for binary output
935: $ FILE_MODE_READ - open existing file for binary input
936: $ FILE_MODE_APPEND - open existing file for binary output
938: Level: advanced
940: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
942: @*/
943: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
944: {
950: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
951: return(0);
952: }
956: /*@
957: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
958: before PetscViewerFileSetName()
960: Logically Collective on PetscViewer
962: Input Parameters:
963: . viewer - the PetscViewer; must be a binary
965: Options Database:
966: -viewer_binary_mpiio : Flag for using MPI-IO
968: Level: advanced
970: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
972: @*/
973: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
974: {
979: PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));
980: return(0);
981: }
986: /*@C
987: PetscViewerFileSetMode - Sets the type of file to be open
989: Logically Collective on PetscViewer
991: Input Parameters:
992: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
993: - type - type of file
994: $ FILE_MODE_WRITE - create new file for binary output
995: $ FILE_MODE_READ - open existing file for binary input
996: $ FILE_MODE_APPEND - open existing file for binary output
998: Level: advanced
1000: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1002: @*/
1003: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1004: {
1010: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1011: return(0);
1012: }
1016: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1017: {
1018: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1021: *type = vbinary->btype;
1022: return(0);
1023: }
1027: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1028: {
1029: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1032: vbinary->btype = type;
1033: return(0);
1034: }
1036: /*
1037: Actually opens the file
1038: */
1041: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1042: {
1043: PetscMPIInt rank;
1044: PetscErrorCode ierr;
1045: size_t len;
1046: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1047: const char *fname;
1048: char bname[PETSC_MAX_PATH_LEN],*gz;
1049: PetscBool found;
1050: PetscFileMode type = vbinary->btype;
1053: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
1054: PetscViewerFileClose_Binary(viewer);
1055: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);
1056: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);
1057: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,NULL);
1059: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1061: /* copy name so we can edit it */
1062: PetscStrallocpy(name,&vbinary->filename);
1064: /* if ends in .gz strip that off and note user wants file compressed */
1065: vbinary->storecompressed = PETSC_FALSE;
1066: if (!rank && type == FILE_MODE_WRITE) {
1067: /* remove .gz if it ends library name */
1068: PetscStrstr(vbinary->filename,".gz",&gz);
1069: if (gz) {
1070: PetscStrlen(gz,&len);
1071: if (len == 3) {
1072: *gz = 0;
1073: vbinary->storecompressed = PETSC_TRUE;
1074: }
1075: }
1076: }
1078: /* only first processor opens file if writeable */
1079: if (!rank || type == FILE_MODE_READ) {
1081: if (type == FILE_MODE_READ) {
1082: /* possibly get the file from remote site or compressed file */
1083: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1084: fname = bname;
1085: if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1086: else if (!found) {
1087: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
1088: fname = 0;
1089: }
1090: } else fname = vbinary->filename;
1092: #if defined(PETSC_HAVE_O_BINARY)
1093: if (type == FILE_MODE_WRITE) {
1094: 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);
1095: } else if (type == FILE_MODE_READ && fname) {
1096: 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);
1097: } else if (type == FILE_MODE_APPEND) {
1098: 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);
1099: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1100: #else
1101: if (type == FILE_MODE_WRITE) {
1102: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1103: } else if (type == FILE_MODE_READ && fname) {
1104: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1105: } else if (type == FILE_MODE_APPEND) {
1106: 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);
1107: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1108: #endif
1109: } else vbinary->fdes = -1;
1111: /*
1112: try to open info file: all processors open this file if read only
1113: */
1114: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1115: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1117: PetscStrcpy(infoname,name);
1118: /* remove .gz if it ends library name */
1119: PetscStrstr(infoname,".gz",&gz);
1120: if (gz) {
1121: PetscStrlen(gz,&len);
1122: if (len == 3) *gz = 0;
1123: }
1125: PetscStrcat(infoname,".info");
1126: PetscFixFilename(infoname,iname);
1127: if (type == FILE_MODE_READ) {
1128: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1129: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);
1130: } else {
1131: vbinary->fdes_info = fopen(infoname,"w");
1132: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1133: }
1134: }
1136: #if defined(PETSC_USE_LOG)
1137: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1138: #endif
1139: return(0);
1140: }
1142: #if defined(PETSC_HAVE_MPIIO)
1145: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
1146: {
1147: PetscMPIInt rank;
1148: PetscErrorCode ierr;
1149: size_t len;
1150: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1151: char *gz;
1152: PetscBool found;
1153: PetscFileMode type = vbinary->btype;
1156: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
1157: PetscViewerFileClose_MPIIO(viewer);
1158: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);
1159: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);
1161: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1162: PetscStrallocpy(name,&vbinary->filename);
1164: vbinary->storecompressed = PETSC_FALSE;
1166: /* only first processor opens file if writeable */
1167: if (type == FILE_MODE_READ) {
1168: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1169: } else if (type == FILE_MODE_WRITE) {
1170: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1171: }
1173: /*
1174: try to open info file: all processors open this file if read only
1176: Below is identical code to the code for Binary above, should be put in seperate routine
1177: */
1178: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1179: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1181: PetscStrcpy(infoname,name);
1182: /* remove .gz if it ends library name */
1183: PetscStrstr(infoname,".gz",&gz);
1184: if (gz) {
1185: PetscStrlen(gz,&len);
1186: if (len == 3) *gz = 0;
1187: }
1189: PetscStrcat(infoname,".info");
1190: PetscFixFilename(infoname,iname);
1191: if (type == FILE_MODE_READ) {
1192: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1193: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);
1194: } else {
1195: vbinary->fdes_info = fopen(infoname,"w");
1196: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1197: }
1198: }
1200: #if defined(PETSC_USE_LOG)
1201: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1202: #endif
1203: return(0);
1204: }
1208: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1209: {
1210: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1211: PetscErrorCode ierr;
1214: if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1215: viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1216: vbinary->MPIIO = PETSC_TRUE;
1217: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_MPIIO);
1218: return(0);
1219: }
1220: #endif
1224: PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1225: {
1226: PetscErrorCode ierr;
1227: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1230: if (binary->filename) {
1231: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1232: }
1233: return(0);
1234: }
1238: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1239: {
1240: PetscErrorCode ierr;
1241: PetscViewer_Binary *vbinary;
1242: #if defined(PETSC_HAVE_MPIIO)
1243: PetscBool useMPIIO = PETSC_FALSE;
1244: #endif
1247: PetscNewLog(v,&vbinary);
1248: v->data = (void*)vbinary;
1249: v->ops->destroy = PetscViewerDestroy_Binary;
1250: v->ops->view = PetscViewerView_Binary;
1251: v->ops->flush = 0;
1252: vbinary->fdes_info = 0;
1253: vbinary->fdes = 0;
1254: vbinary->skipinfo = PETSC_FALSE;
1255: vbinary->skipoptions = PETSC_TRUE;
1256: vbinary->skipheader = PETSC_FALSE;
1257: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1258: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1259: vbinary->btype = (PetscFileMode) -1;
1260: vbinary->storecompressed = PETSC_FALSE;
1261: vbinary->filename = 0;
1262: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1264: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1265: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1266: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1267: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1268: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1269: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1270: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1271: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1272: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1273: #if defined(PETSC_HAVE_MPIIO)
1274: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);
1276: PetscOptionsGetBool(NULL,"-viewer_binary_mpiio",&useMPIIO,NULL);
1277: if (useMPIIO) {
1278: PetscViewerBinarySetMPIIO(v);
1279: }
1280: #endif
1281: return(0);
1282: }
1284: /* ---------------------------------------------------------------------*/
1285: /*
1286: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1287: is attached to a communicator, in this case the attribute is a PetscViewer.
1288: */
1289: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1293: /*@C
1294: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1295: in a communicator.
1297: Collective on MPI_Comm
1299: Input Parameter:
1300: . comm - the MPI communicator to share the binary PetscViewer
1302: Level: intermediate
1304: Options Database Keys:
1305: + -viewer_binary_filename <name>
1306: . -viewer_binary_skip_info
1307: - -viewer_binary_skip_options
1309: Environmental variables:
1310: - PETSC_VIEWER_BINARY_FILENAME
1312: Notes:
1313: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1314: an error code. The binary PetscViewer is usually used in the form
1315: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1317: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1318: PetscViewerDestroy()
1319: @*/
1320: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1321: {
1323: PetscBool flg;
1324: PetscViewer viewer;
1325: char fname[PETSC_MAX_PATH_LEN];
1326: MPI_Comm ncomm;
1329: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1330: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1331: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1332: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1333: }
1334: MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1335: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1336: if (!flg) { /* PetscViewer not yet created */
1337: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1338: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1339: if (!flg) {
1340: PetscStrcpy(fname,"binaryoutput");
1341: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1342: }
1343: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1344: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1345: PetscObjectRegisterDestroy((PetscObject)viewer);
1346: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1347: MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1348: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1349: }
1350: PetscCommDestroy(&ncomm);
1351: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1352: PetscFunctionReturn(viewer);
1353: }