Actual source code: binv.c
1: #define PETSC_DLL
2: #include src/sys/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: PetscFileMode 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(((PetscObject)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(((PetscObject)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 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 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 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 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 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: PetscMPIInt rank;
228: int err;
231: MPI_Comm_rank(((PetscObject)v)->comm,&rank);
232: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
233: close(vbinary->fdes);
234: if (!rank && vbinary->storecompressed) {
235: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
236: FILE *fp;
237: /* compress the file */
238: PetscStrcpy(par,"gzip ");
239: PetscStrcat(par,vbinary->filename);
240: #if defined(PETSC_HAVE_POPEN)
241: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
242: if (fgets(buf,1024,fp)) {
243: SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
244: }
245: PetscPClose(PETSC_COMM_SELF,fp);
246: #else
247: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
248: #endif
249: }
250: }
251: if (vbinary->fdes_info) {
252: err = fclose(vbinary->fdes_info);
253: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
254: }
255: PetscStrfree(vbinary->filename);
256: PetscFree(vbinary);
257: return(0);
258: }
262: /*@
263: PetscViewerBinaryCreate - Create a binary viewer.
265: Collective on MPI_Comm
267: Input Parameters:
268: . comm - MPI communicator
270: Output Parameter:
271: . binv - PetscViewer for binary input/output
273: Level: beginner
274: @*/
275: PetscErrorCode PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
276: {
278:
280: PetscViewerCreate(comm,binv);
281: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
282: return(0);
283: }
287: /*@C
288: PetscViewerBinaryOpen - Opens a file for binary input/output.
290: Collective on MPI_Comm
292: Input Parameters:
293: + comm - MPI communicator
294: . name - name of file
295: - type - type of file
296: $ FILE_MODE_WRITE - create new file for binary output
297: $ FILE_MODE_READ - open existing file for binary input
298: $ FILE_MODE_APPEND - open existing file for binary output
300: Output Parameter:
301: . binv - PetscViewer for binary input/output to use with the specified file
303: Level: beginner
305: Note:
306: This PetscViewer should be destroyed with PetscViewerDestroy().
308: For reading files, the filename may begin with ftp:// or http:// and/or
309: end with .gz; in this case file is brought over and uncompressed.
311: For creating files, if the file name ends with .gz it is automatically
312: compressed when closed.
314: For writing files it only opens the file on processor 0 in the communicator.
315: For readable files it opens the file on all nodes that have the file. If
316: node 0 does not have the file it generates an error even if other nodes
317: do have the file.
319: Concepts: binary files
320: Concepts: PetscViewerBinary^creating
321: Concepts: gzip
322: Concepts: accessing remote file
323: Concepts: remote file
325: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
326: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
327: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
328: @*/
329: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
330: {
332:
334: PetscViewerCreate(comm,binv);
335: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
336: PetscViewerFileSetMode(*binv,type);
337: PetscViewerFileSetName(*binv,name);
338: return(0);
339: }
343: /*@C
344: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
346: Collective on MPI_Comm
348: Input Parameters:
349: + viewer - the binary viewer
350: . data - location to write the data
351: . count - number of items of data to read
352: - datatype - type of data to read
354: Level: beginner
356: Concepts: binary files
358: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
359: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
360: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
361: @*/
362: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
363: {
364: PetscErrorCode ierr;
365: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
367: PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
368: return(0);
369: }
373: /*@C
374: PetscViewerBinaryWrite - writes to a binary file, only from the first process
376: Collective on MPI_Comm
378: Input Parameters:
379: + viewer - the binary viewer
380: . data - location of data
381: . count - number of items of data to read
382: . istemp - data may be overwritten
383: - datatype - type of data to read
385: Level: beginner
387: Concepts: binary files
389: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
390: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
391: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
392: @*/
393: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
394: {
395: PetscErrorCode ierr;
396: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
398: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
399: return(0);
400: }
404: /*@C
405: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
407: Collective on MPI_Comm
409: Input Parameters:
410: + viewer - the binary viewer
411: - data - location of the array of strings
414: Level: intermediate
416: Concepts: binary files
418: Notes: array of strings is null terminated
420: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
421: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
422: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
423: @*/
424: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
425: {
426: PetscErrorCode ierr;
427: PetscInt i,n = 0,*sizes;
429: /* count number of strings */
430: while (data[n++]);
431: n--;
432: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
433: sizes[0] = n;
434: for (i=0; i<n; i++) {
435: size_t tmp;
436: PetscStrlen(data[i],&tmp);
437: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
438: }
439: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
440: for (i=0; i<n; i++) {
441: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
442: }
443: PetscFree(sizes);
444: return(0);
445: }
447: /*@C
448: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
450: Collective on MPI_Comm
452: Input Parameter:
453: . viewer - the binary viewer
455: Output Parameter:
456: . data - location of the array of strings
458: Level: intermediate
460: Concepts: binary files
462: Notes: array of strings is null terminated
464: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
465: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
466: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
467: @*/
468: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
469: {
470: PetscErrorCode ierr;
471: PetscInt i,n,*sizes,N = 0;
473: /* count number of strings */
474: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
475: PetscMalloc(n*sizeof(PetscInt),&sizes);
476: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
477: for (i=0; i<n; i++) {
478: N += sizes[i];
479: }
480: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
481: (*data)[0] = (char*)((*data) + n + 1);
482: for (i=1; i<n; i++) {
483: (*data)[i] = (*data)[i-1] + sizes[i-1];
484: }
485: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
486: (*data)[n] = 0;
487: PetscFree(sizes);
488: return(0);
489: }
493: /*@C
494: PetscViewerFileGetMode - Gets the type of file to be open
496: Collective on PetscViewer
498: Input Parameter:
499: . viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
501: Output Parameter:
502: . type - type of file
503: $ FILE_MODE_WRITE - create new file for binary output
504: $ FILE_MODE_READ - open existing file for binary input
505: $ FILE_MODE_APPEND - open existing file for binary output
507: Level: advanced
509: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
511: @*/
512: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
513: {
514: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);
519: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
520: if (f) {
521: (*f)(viewer,type);
522: }
523: return(0);
524: }
528: /*@C
529: PetscViewerFileSetMode - Sets the type of file to be open
531: Collective on PetscViewer
533: Input Parameters:
534: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
535: - type - type of file
536: $ FILE_MODE_WRITE - create new file for binary output
537: $ FILE_MODE_READ - open existing file for binary input
538: $ FILE_MODE_APPEND - open existing file for binary output
540: Level: advanced
542: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
544: @*/
545: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
546: {
547: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);
551: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
552: if (f) {
553: (*f)(viewer,type);
554: }
555: return(0);
556: }
561: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
562: {
563: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
566: *type = vbinary->btype;
567: return(0);
568: }
574: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
575: {
576: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
579: vbinary->btype = type;
580: return(0);
581: }
586: /*@
587: PetscViewerBinaryLoadInfo - Loads options from the name.info file
588: if it exists.
590: Collective on PetscViewer
592: Input Parameter:
593: . viewer - the binary viewer whose options you wish to load
595: Level: developer
597: @*/
598: PetscErrorCode PetscViewerBinaryLoadInfo(PetscViewer viewer)
599: {
600: FILE *file;
601: char string[256],*first,*second,*final;
602: size_t len;
603: PetscErrorCode ierr;
604: PetscToken token;
605: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
608: if (vbinary->skipinfo) return(0);
610: PetscViewerBinaryGetInfoPointer(viewer,&file);
611: if (!file) return(0);
613: /* read rows of the file adding them to options database */
614: while (fgets(string,256,file)) {
615: /* Comments are indicated by #, ! or % in the first column */
616: if (string[0] == '#') continue;
617: if (string[0] == '!') continue;
618: if (string[0] == '%') continue;
619: PetscTokenCreate(string,' ',&token);
620: PetscTokenFind(token,&first);
621: PetscTokenFind(token,&second);
622: if (first && first[0] == '-') {
623: PetscTruth wrongtype;
624: /*
625: Check for -mat_complex or -mat_double
626: */
627: #if defined(PETSC_USE_COMPLEX)
628: PetscStrncmp(first,"-mat_double",11,&wrongtype);
629: if (wrongtype) {
630: SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading double number matrix with complex number code");
631: }
632: #else
633: PetscStrncmp(first,"-mat_complex",12,&wrongtype);
634: if (wrongtype) {
635: SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading complex number matrix with double number code");
636: }
637: #endif
639: if (second) {final = second;} else {final = first;}
640: PetscStrlen(final,&len);
641: while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
642: len--; final[len] = 0;
643: }
644: PetscOptionsSetValue(first,second);
645: }
646: PetscTokenDestroy(token);
647: }
648: return(0);
649: }
651: /*
652: Actually opens the file
653: */
657: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
658: {
659: PetscMPIInt rank;
660: PetscErrorCode ierr;
661: size_t len;
662: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
663: const char *fname;
664: char bname[PETSC_MAX_PATH_LEN],*gz;
665: PetscTruth found;
666: PetscFileMode type = vbinary->btype;
667: int err;
670: if (type == (PetscFileMode) -1) {
671: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
672: }
673: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
674: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
676: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
678: /* copy name so we can edit it */
679: PetscStrallocpy(name,&vbinary->filename);
681: /* if ends in .gz strip that off and note user wants file compressed */
682: vbinary->storecompressed = PETSC_FALSE;
683: if (!rank && type == FILE_MODE_WRITE) {
684: /* remove .gz if it ends library name */
685: PetscStrstr(vbinary->filename,".gz",&gz);
686: if (gz) {
687: PetscStrlen(gz,&len);
688: if (len == 3) {
689: *gz = 0;
690: vbinary->storecompressed = PETSC_TRUE;
691: }
692: }
693: }
695: /* only first processor opens file if writeable */
696: if (!rank || type == FILE_MODE_READ) {
698: if (type == FILE_MODE_READ){
699: /* possibly get the file from remote site or compressed file */
700: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
701: fname = bname;
702: if (!rank && !found) {
703: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
704: } else if (!found) {
705: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
706: fname = 0;
707: }
708: } else {
709: fname = vbinary->filename;
710: }
712: #if defined(PETSC_HAVE_O_BINARY)
713: if (type == FILE_MODE_WRITE) {
714: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
715: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
716: }
717: } else if (type == FILE_MODE_READ && fname) {
718: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
719: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
720: }
721: } else if (type == FILE_MODE_APPEND) {
722: if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
723: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
724: }
725: } else if (fname) {
726: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
727: }
728: #else
729: if (type == FILE_MODE_WRITE) {
730: if ((vbinary->fdes = creat(fname,0666)) == -1) {
731: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
732: }
733: } else if (type == FILE_MODE_READ && fname) {
734: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
735: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
736: }
737: } else if (type == FILE_MODE_APPEND) {
738: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
739: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
740: }
741: } else if (fname) {
742: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
743: }
744: #endif
745: } else vbinary->fdes = -1;
746: viewer->format = PETSC_VIEWER_NOFORMAT;
748: /*
749: try to open info file: all processors open this file if read only
750: */
751: if (!rank || type == FILE_MODE_READ) {
752: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
753:
754: PetscStrcpy(infoname,name);
755: /* remove .gz if it ends library name */
756: PetscStrstr(infoname,".gz",&gz);
757: if (gz) {
758: PetscStrlen(gz,&len);
759: if (len == 3) {
760: *gz = 0;
761: }
762: }
763:
764: PetscStrcat(infoname,".info");
765: PetscFixFilename(infoname,iname);
766: if (type == FILE_MODE_READ) {
767: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
768: if (found) {
769: vbinary->fdes_info = fopen(infoname,"r");
770: if (vbinary->fdes_info) {
771: PetscViewerBinaryLoadInfo(viewer);
772: err = fclose(vbinary->fdes_info);
773: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
774: }
775: vbinary->fdes_info = fopen(infoname,"r");
776: }
777: } else if (!vbinary->skipinfo) {
778: vbinary->fdes_info = fopen(infoname,"w");
779: if (!vbinary->fdes_info) {
780: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
781: }
782: }
783: }
785: #if defined(PETSC_USE_LOG)
786: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
787: #endif
788: return(0);
789: }
795: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
796: {
797: PetscErrorCode ierr;
798: PetscViewer_Binary *vbinary;
801: PetscNewLog(v,PetscViewer_Binary,&vbinary);
802: v->data = (void*)vbinary;
803: v->ops->destroy = PetscViewerDestroy_Binary;
804: v->ops->flush = 0;
805: v->iformat = 0;
806: vbinary->fdes_info = 0;
807: vbinary->fdes = 0;
808: vbinary->skipinfo = PETSC_FALSE;
809: vbinary->skipoptions = PETSC_TRUE;
810: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
811: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
812: vbinary->btype = (PetscFileMode) -1;
813: vbinary->storecompressed = PETSC_FALSE;
814: vbinary->filename = 0;
816: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
817: "PetscViewerFileSetName_Binary",
818: PetscViewerFileSetName_Binary);
819: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
820: "PetscViewerFileSetMode_Binary",
821: PetscViewerFileSetMode_Binary);
822: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
823: "PetscViewerFileGetMode_Binary",
824: PetscViewerFileGetMode_Binary);
825: return(0);
826: }
830: /* ---------------------------------------------------------------------*/
831: /*
832: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
833: is attached to a communicator, in this case the attribute is a PetscViewer.
834: */
835: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
839: /*@C
840: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
841: in a communicator.
843: Collective on MPI_Comm
845: Input Parameter:
846: . comm - the MPI communicator to share the binary PetscViewer
847:
848: Level: intermediate
850: Options Database Keys:
851: $ -viewer_binary_filename <name>
853: Environmental variables:
854: - PETSC_VIEWER_BINARY_FILENAME
856: Notes:
857: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
858: an error code. The binary PetscViewer is usually used in the form
859: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
861: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
862: PetscViewerDestroy()
863: @*/
864: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
865: {
867: PetscTruth flg;
868: PetscViewer viewer;
869: char fname[PETSC_MAX_PATH_LEN];
872: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
873: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
874: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
875: }
876: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
877: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
878: if (!flg) { /* PetscViewer not yet created */
879: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
880: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
881: if (!flg) {
882: PetscStrcpy(fname,"binaryoutput");
883: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
884: }
885: PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
886: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
887: PetscObjectRegisterDestroy((PetscObject)viewer);
888: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
889: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
890: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
891: }
892: PetscFunctionReturn(viewer);
893: }