Actual source code: binv.c
1: #define PETSC_DLL
2: #include src/sys/src/viewer/viewerimpl.h
3: #include petscsys.h
4: #include <fcntl.h>
5: #if defined(PETSC_HAVE_UNISTD_H)
6: #include <unistd.h>
7: #endif
8: #if defined (PETSC_HAVE_IO_H)
9: #include <io.h>
10: #endif
12: typedef struct {
13: int fdes; /* file descriptor */
14: PetscViewerFileType btype; /* read or write? */
15: FILE *fdes_info; /* optional file containing info on binary file*/
16: PetscTruth storecompressed; /* gzip the write binary file when closing it*/
17: char *filename;
18: PetscTruth skipinfo; /* Don't create info file for writing; don't use for reading */
19: PetscTruth skipoptions; /* don't use PETSc options database when loading */
20: } PetscViewer_Binary;
24: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
25: {
26: int rank;
27: PetscErrorCode ierr;
28: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
31: MPI_Comm_rank(viewer->comm,&rank);
32: if (!rank) {
33: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
34: PetscViewerSetType(*outviewer,PETSC_VIEWER_BINARY);
35: obinary = (PetscViewer_Binary*)(*outviewer)->data;
36: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
37: } else {
38: *outviewer = 0;
39: }
40: return(0);
41: }
45: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
46: {
48: PetscErrorCode rank;
51: MPI_Comm_rank(viewer->comm,&rank);
52: if (!rank) {
53: PetscFree((*outviewer)->data);
54: PetscHeaderDestroy(*outviewer);
55: }
56: return(0);
57: }
61: /*@C
62: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
64: Not Collective
66: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
67: - fdes - file descriptor
69: Level: advanced
71: Notes:
72: For writable binary PetscViewers, the descriptor will only be valid for the
73: first processor in the communicator that shares the PetscViewer. For readable
74: files it will only be valid on nodes that have the file. If node 0 does not
75: have the file it generates an error even if another node does have the file.
76:
77: Fortran Note:
78: This routine is not supported in Fortran.
80: Concepts: file descriptor^getting
81: Concepts: PetscViewerBinary^accessing file descriptor
83: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
84: @*/
85: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
86: {
87: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
90: *fdes = vbinary->fdes;
91: return(0);
92: }
96: /*@
97: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
99: Not Collective
101: Input Paramter:
102: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
104: Options Database Key:
105: . -viewer_binary_skip_info
107: Level: advanced
109: Notes: This must be called after PetscViewerSetType() but before PetscViewerBinarySetFilename()
111: Concepts: PetscViewerBinary^accessing info file
113: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
114: PetscViewerBinaryGetSkipOptions()
115: @*/
116: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinarySkipInfo(PetscViewer viewer)
117: {
118: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
121: vbinary->skipinfo = PETSC_TRUE;
122: return(0);
123: }
127: /*@
128: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
130: Not Collective
132: Input Paramter:
133: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
134: - skip - PETSC_TRUE means do not use
136: Options Database Key:
137: . -viewer_binary_skip_options
139: Level: advanced
141: Notes: This must be called after PetscViewerSetType()
143: Concepts: PetscViewerBinary^accessing info file
145: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
146: PetscViewerBinaryGetSkipOptions()
147: @*/
148: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
149: {
150: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
153: vbinary->skipoptions = skip;
154: return(0);
155: }
159: /*@
160: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
162: Not Collective
164: Input Paramter:
165: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
167: Output Parameter:
168: . skip - PETSC_TRUE means do not use
170: Level: advanced
172: Notes: This must be called after PetscViewerSetType()
174: Concepts: PetscViewerBinary^accessing info file
176: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
177: PetscViewerBinarySetSkipOptions()
178: @*/
179: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
180: {
181: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
184: *skip = vbinary->skipoptions;
185: return(0);
186: }
190: /*@C
191: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
192: info file associated with a binary file.
194: Not Collective
196: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
197: - file - file pointer
199: Level: advanced
201: Notes:
202: For writable binary PetscViewers, the descriptor will only be valid for the
203: first processor in the communicator that shares the PetscViewer.
204:
205: Fortran Note:
206: This routine is not supported in Fortran.
208: Concepts: PetscViewerBinary^accessing info file
210: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
211: @*/
212: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
213: {
214: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
217: *file = vbinary->fdes_info;
218: return(0);
219: }
223: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
224: {
225: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
226: PetscErrorCode ierr;
227: int rank;
230: MPI_Comm_rank(v->comm,&rank);
231: if ((!rank || vbinary->btype == PETSC_FILE_RDONLY ) && vbinary->fdes) {
232: close(vbinary->fdes);
233: if (!rank && vbinary->storecompressed) {
234: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
235: FILE *fp;
236: /* compress the file */
237: PetscStrcpy(par,"gzip ");
238: PetscStrcat(par,vbinary->filename);
239: #if defined(PETSC_HAVE_POPEN)
240: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
241: if (fgets(buf,1024,fp)) {
242: SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
243: }
244: PetscPClose(PETSC_COMM_SELF,fp);
245: #else
246: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
247: #endif
248: }
249: }
250: if (vbinary->fdes_info) fclose(vbinary->fdes_info);
251: PetscStrfree(vbinary->filename);
252: PetscFree(vbinary);
253: return(0);
254: }
258: /*@C
259: PetscViewerBinaryOpen - Opens a file for binary input/output.
261: Collective on MPI_Comm
263: Input Parameters:
264: + comm - MPI communicator
265: . name - name of file
266: - type - type of file
267: $ PETSC_FILE_CREATE - create new file for binary output
268: $ PETSC_FILE_RDONLY - open existing file for binary input
269: $ PETSC_FILE_WRONLY - open existing file for binary output
271: Output Parameter:
272: . binv - PetscViewer for binary input/output to use with the specified file
274: Level: beginner
276: Note:
277: This PetscViewer should be destroyed with PetscViewerDestroy().
279: For reading files, the filename may begin with ftp:// or http:// and/or
280: end with .gz; in this case file is brought over and uncompressed.
282: For creating files, if the file name ends with .gz it is automatically
283: compressed when closed.
285: For writing files it only opens the file on processor 0 in the communicator.
286: For readable files it opens the file on all nodes that have the file. If
287: node 0 does not have the file it generates an error even if other nodes
288: do have the file.
290: Concepts: binary files
291: Concepts: PetscViewerBinary^creating
292: Concepts: gzip
293: Concepts: accessing remote file
294: Concepts: remote file
296: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
297: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
298: PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
299: @*/
300: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscViewerFileType type,PetscViewer *binv)
301: {
303:
305: PetscViewerCreate(comm,binv);
306: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
307: PetscViewerSetFileType(*binv,type);
308: PetscViewerSetFilename(*binv,name);
309: return(0);
310: }
314: /*@C
315: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
317: Collective on MPI_Comm
319: Input Parameters:
320: + viewer - the binary viewer
321: . data - location to write the data
322: . count - number of items of data to read
323: - datatype - type of data to read
325: Level: beginner
327: Concepts: binary files
329: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
330: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
331: PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
332: @*/
333: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
334: {
335: PetscErrorCode ierr;
336: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
338: PetscSynchronizedBinaryRead(viewer->comm,vbinary->fdes,data,count,dtype);
339: return(0);
340: }
344: /*@C
345: PetscViewerBinaryWrite - writes to a binary file, only from the first process
347: Collective on MPI_Comm
349: Input Parameters:
350: + viewer - the binary viewer
351: . data - location of data
352: . count - number of items of data to read
353: . istemp - data may be overwritten
354: - datatype - type of data to read
356: Level: beginner
358: Concepts: binary files
360: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
361: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
362: PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
363: @*/
364: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
365: {
366: PetscErrorCode ierr;
367: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
369: PetscSynchronizedBinaryWrite(viewer->comm,vbinary->fdes,data,count,dtype,istemp);
370: return(0);
371: }
375: /*@C
376: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
378: Collective on MPI_Comm
380: Input Parameters:
381: + viewer - the binary viewer
382: - data - location of the array of strings
385: Level: intermediate
387: Concepts: binary files
389: Notes: array of strings is null terminated
391: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
392: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
393: PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
394: @*/
395: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
396: {
397: PetscErrorCode ierr;
398: PetscInt i,n = 0,*sizes;
400: /* count number of strings */
401: while (data[n++]);
402: n--;
403: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
404: sizes[0] = n;
405: for (i=0; i<n; i++) {
406: size_t tmp;
407: PetscStrlen(data[i],&tmp);
408: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
409: }
410: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
411: for (i=0; i<n; i++) {
412: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
413: }
414: PetscFree(sizes);
415: return(0);
416: }
418: /*@C
419: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
421: Collective on MPI_Comm
423: Input Parameter:
424: . viewer - the binary viewer
426: Output Parameter:
427: . data - location of the array of strings
429: Level: intermediate
431: Concepts: binary files
433: Notes: array of strings is null terminated
435: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
436: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
437: PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
438: @*/
439: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
440: {
441: PetscErrorCode ierr;
442: PetscInt i,n,*sizes,N = 0;
444: /* count number of strings */
445: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
446: PetscMalloc(n*sizeof(PetscInt),&sizes);
447: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
448: for (i=0; i<n; i++) {
449: N += sizes[i];
450: }
451: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
452: (*data)[0] = (char*)((*data) + n + 1);
453: for (i=1; i<n; i++) {
454: (*data)[i] = (*data)[i-1] + sizes[i-1];
455: }
456: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
457: (*data)[n] = 0;
458: PetscFree(sizes);
459: return(0);
460: }
464: /*@C
465: PetscViewerSetFileType - Sets the type of file to be open
467: Collective on PetscViewer
469: Input Parameters:
470: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
471: - type - type of file
472: $ PETSC_FILE_CREATE - create new file for binary output
473: $ PETSC_FILE_RDONLY - open existing file for binary input
474: $ PETSC_FILE_WRONLY - open existing file for binary output
476: Level: advanced
478: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
480: @*/
481: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFileType(PetscViewer viewer,PetscViewerFileType type)
482: {
483: PetscErrorCode ierr,(*f)(PetscViewer,PetscViewerFileType);
487: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFileType_C",(void (**)(void))&f);
488: if (f) {
489: (*f)(viewer,type);
490: }
491: return(0);
492: }
497: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFileType_Binary(PetscViewer viewer,PetscViewerFileType type)
498: {
499: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
502: vbinary->btype = type;
503: return(0);
504: }
509: /*@
510: PetscViewerBinaryLoadInfo - Loads options from the name.info file
511: if it exists.
513: Collective on PetscViewer
515: Input Parameter:
516: . viewer - the binary viewer whose options you wish to load
518: Level: developer
520: @*/
521: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryLoadInfo(PetscViewer viewer)
522: {
523: FILE *file;
524: char string[256],*first,*second,*final;
525: size_t len;
526: PetscErrorCode ierr;
527: PetscToken *token;
528: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
531: if (vbinary->skipinfo) return(0);
533: PetscViewerBinaryGetInfoPointer(viewer,&file);
534: if (!file) return(0);
536: /* read rows of the file adding them to options database */
537: while (fgets(string,256,file)) {
538: /* Comments are indicated by #, ! or % in the first column */
539: if (string[0] == '#') continue;
540: if (string[0] == '!') continue;
541: if (string[0] == '%') continue;
542: PetscTokenCreate(string,' ',&token);
543: PetscTokenFind(token,&first);
544: PetscTokenFind(token,&second);
545: if (first && first[0] == '-') {
546: PetscTruth wrongtype;
547: /*
548: Check for -mat_complex or -mat_double
549: */
550: #if defined(PETSC_USE_COMPLEX)
551: PetscStrncmp(first,"-mat_double",11,&wrongtype);
552: if (wrongtype) {
553: SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading double number matrix with complex number code");
554: }
555: #else
556: PetscStrncmp(first,"-mat_complex",12,&wrongtype);
557: if (wrongtype) {
558: SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading complex number matrix with double number code");
559: }
560: #endif
562: if (second) {final = second;} else {final = first;}
563: PetscStrlen(final,&len);
564: while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
565: len--; final[len] = 0;
566: }
567: PetscOptionsSetValue(first,second);
568: }
569: PetscTokenDestroy(token);
570: }
571: return(0);
572: }
574: /*
575: Actually opens the file
576: */
580: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename_Binary(PetscViewer viewer,const char name[])
581: {
582: int rank;
583: PetscErrorCode ierr;
584: size_t len;
585: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
586: const char *fname;
587: char bname[PETSC_MAX_PATH_LEN],*gz;
588: PetscTruth found;
589: PetscViewerFileType type = vbinary->btype;
592: if (type == (PetscViewerFileType) -1) {
593: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetType() before PetscViewerSetFilename()");
594: }
595: PetscOptionsGetTruth(viewer->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
596: PetscOptionsGetTruth(viewer->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
598: MPI_Comm_rank(viewer->comm,&rank);
600: /* copy name so we can edit it */
601: PetscStrallocpy(name,&vbinary->filename);
603: /* if ends in .gz strip that off and note user wants file compressed */
604: vbinary->storecompressed = PETSC_FALSE;
605: if (!rank && type == PETSC_FILE_CREATE) {
606: /* remove .gz if it ends library name */
607: PetscStrstr(vbinary->filename,".gz",&gz);
608: if (gz) {
609: PetscStrlen(gz,&len);
610: if (len == 3) {
611: *gz = 0;
612: vbinary->storecompressed = PETSC_TRUE;
613: }
614: }
615: }
617: /* only first processor opens file if writeable */
618: if (!rank || type == PETSC_FILE_RDONLY) {
620: if (type == PETSC_FILE_RDONLY){
621: /* possibly get the file from remote site or compressed file */
622: PetscFileRetrieve(viewer->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
623: fname = bname;
624: if (!rank && !found) {
625: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
626: } else if (!found) {
627: PetscLogInfo((viewer,"PetscViewerSetFilename_Binary:Nonzero processor did not locate readonly file\n"));
628: fname = 0;
629: }
630: } else {
631: fname = vbinary->filename;
632: }
634: #if defined(PETSC_HAVE_O_BINARY)
635: if (type == PETSC_FILE_CREATE) {
636: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
637: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
638: }
639: } else if (type == PETSC_FILE_RDONLY && fname) {
640: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
641: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
642: }
643: } else if (type == PETSC_FILE_WRONLY) {
644: if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
645: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
646: }
647: } else if (fname) {
648: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
649: }
650: #else
651: if (type == PETSC_FILE_CREATE) {
652: if ((vbinary->fdes = creat(fname,0666)) == -1) {
653: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
654: }
655: } else if (type == PETSC_FILE_RDONLY && fname) {
656: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
657: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
658: }
659: } else if (type == PETSC_FILE_WRONLY) {
660: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
661: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
662: }
663: } else if (fname) {
664: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
665: }
666: #endif
667: } else vbinary->fdes = -1;
668: viewer->format = PETSC_VIEWER_NOFORMAT;
670: /*
671: try to open info file: all processors open this file if read only
672: */
673: if (!rank || type == PETSC_FILE_RDONLY) {
674: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
675:
676: PetscStrcpy(infoname,name);
677: /* remove .gz if it ends library name */
678: PetscStrstr(infoname,".gz",&gz);
679: if (gz) {
680: PetscStrlen(gz,&len);
681: if (len == 3) {
682: *gz = 0;
683: }
684: }
685:
686: PetscStrcat(infoname,".info");
687: PetscFixFilename(infoname,iname);
688: if (type == PETSC_FILE_RDONLY) {
689: PetscFileRetrieve(viewer->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
690: if (found) {
691: vbinary->fdes_info = fopen(infoname,"r");
692: if (vbinary->fdes_info) {
693: PetscViewerBinaryLoadInfo(viewer);
694: fclose(vbinary->fdes_info);
695: }
696: vbinary->fdes_info = fopen(infoname,"r");
697: }
698: } else if (!vbinary->skipinfo) {
699: vbinary->fdes_info = fopen(infoname,"w");
700: if (!vbinary->fdes_info) {
701: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
702: }
703: }
704: }
706: #if defined(PETSC_USE_LOG)
707: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
708: #endif
709: return(0);
710: }
716: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_Binary(PetscViewer v)
717: {
718: PetscErrorCode ierr;
719: PetscViewer_Binary *vbinary;
722: PetscNew(PetscViewer_Binary,&vbinary);
723: v->data = (void*)vbinary;
724: v->ops->destroy = PetscViewerDestroy_Binary;
725: v->ops->flush = 0;
726: v->iformat = 0;
727: vbinary->fdes_info = 0;
728: vbinary->fdes = 0;
729: vbinary->skipinfo = PETSC_FALSE;
730: vbinary->skipoptions = PETSC_TRUE;
731: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
732: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
733: vbinary->btype = (PetscViewerFileType) -1;
734: vbinary->storecompressed = PETSC_FALSE;
735: vbinary->filename = 0;
737: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerSetFilename_C",
738: "PetscViewerSetFilename_Binary",
739: PetscViewerSetFilename_Binary);
740: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerSetFileType_C",
741: "PetscViewerSetFileType_Binary",
742: PetscViewerSetFileType_Binary);
743: return(0);
744: }
748: /* ---------------------------------------------------------------------*/
749: /*
750: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
751: is attached to a communicator, in this case the attribute is a PetscViewer.
752: */
753: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
757: /*@C
758: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
759: in a communicator.
761: Collective on MPI_Comm
763: Input Parameter:
764: . comm - the MPI communicator to share the binary PetscViewer
765:
766: Level: intermediate
768: Options Database Keys:
769: $ -viewer_binary_filename <name>
771: Environmental variables:
772: - PETSC_VIEWER_BINARY_FILENAME
774: Notes:
775: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
776: an error code. The binary PetscViewer is usually used in the form
777: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
779: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
780: PetscViewerDestroy()
781: @*/
782: PetscViewer PETSC_DLLEXPORT PETSC_VIEWER_BINARY_(MPI_Comm comm)
783: {
785: PetscTruth flg;
786: PetscViewer viewer;
787: char fname[PETSC_MAX_PATH_LEN];
790: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
791: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
792: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
793: }
794: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
795: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
796: if (!flg) { /* PetscViewer not yet created */
797: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
798: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
799: if (!flg) {
800: PetscStrcpy(fname,"binaryoutput");
801: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
802: }
803: PetscViewerBinaryOpen(comm,fname,PETSC_FILE_CREATE,&viewer);
804: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
805: PetscObjectRegisterDestroy((PetscObject)viewer);
806: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
807: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
808: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
809: }
810: PetscFunctionReturn(viewer);
811: }