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, ignored if using MPI IO */
14: #if defined(PETSC_HAVE_MPIIO)
15: PetscTruth MPIIO;
16: MPI_File mfdes; /* ignored unless using MPI IO */
17: MPI_Offset moff;
18: #endif
19: PetscFileMode btype; /* read or write? */
20: FILE *fdes_info; /* optional file containing info on binary file*/
21: PetscTruth storecompressed; /* gzip the write binary file when closing it*/
22: char *filename;
23: PetscTruth skipinfo; /* Don't create info file for writing; don't use for reading */
24: PetscTruth skipoptions; /* don't use PETSc options database when loading */
25: } PetscViewer_Binary;
29: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
30: {
31: int rank;
32: PetscErrorCode ierr;
33: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
36: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
37: if (!rank) {
38: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
39: PetscViewerSetType(*outviewer,PETSC_VIEWER_BINARY);
40: obinary = (PetscViewer_Binary*)(*outviewer)->data;
41: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
42: } else {
43: *outviewer = 0;
44: }
45: return(0);
46: }
50: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
51: {
53: PetscErrorCode rank;
56: MPI_Comm_rank(((PetscObject)viewer)->comm,&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: Level: advanced
178: Fortran Note:
179: This routine is not supported in Fortran.
181: Concepts: file descriptor^getting
182: Concepts: PetscViewerBinary^accessing file descriptor
184: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
185: @*/
186: PetscErrorCode PetscViewerBinaryGetMPIIO(PetscViewer viewer,PetscTruth *flg)
187: {
188: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
191: *flg = vbinary->MPIIO;
192: return(0);
193: }
194: #endif
198: /*@C
199: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
201: Not Collective
203: Input Parameter:
204: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
206: Output Parameter:
207: . fdes - file descriptor
209: Level: advanced
211: Notes:
212: For writable binary PetscViewers, the descriptor will only be valid for the
213: first processor in the communicator that shares the PetscViewer. For readable
214: files it will only be valid on nodes that have the file. If node 0 does not
215: have the file it generates an error even if another node does have the file.
216:
217: Fortran Note:
218: This routine is not supported in Fortran.
220: Concepts: file descriptor^getting
221: Concepts: PetscViewerBinary^accessing file descriptor
223: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
224: @*/
225: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
226: {
227: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
230: *fdes = vbinary->fdes;
231: return(0);
232: }
236: /*@
237: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
239: Not Collective
241: Input Paramter:
242: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
244: Options Database Key:
245: . -viewer_binary_skip_info
247: Level: advanced
249: Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName()
251: Concepts: PetscViewerBinary^accessing info file
253: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
254: PetscViewerBinaryGetSkipOptions()
255: @*/
256: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
257: {
258: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
261: vbinary->skipinfo = PETSC_TRUE;
262: return(0);
263: }
267: /*@
268: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
270: Not Collective
272: Input Parameters:
273: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
274: - skip - PETSC_TRUE means do not use
276: Options Database Key:
277: . -viewer_binary_skip_options
279: Level: advanced
281: Notes: This must be called after PetscViewerSetType()
283: Concepts: PetscViewerBinary^accessing info file
285: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
286: PetscViewerBinaryGetSkipOptions()
287: @*/
288: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
289: {
290: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
293: vbinary->skipoptions = skip;
294: return(0);
295: }
299: /*@
300: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
302: Not Collective
304: Input Parameter:
305: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
307: Output Parameter:
308: . skip - PETSC_TRUE means do not use
310: Level: advanced
312: Notes: This must be called after PetscViewerSetType()
314: Concepts: PetscViewerBinary^accessing info file
316: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
317: PetscViewerBinarySetSkipOptions()
318: @*/
319: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
320: {
321: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
324: *skip = vbinary->skipoptions;
325: return(0);
326: }
330: /*@C
331: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
332: info file associated with a binary file.
334: Not Collective
336: Input Parameter:
337: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
339: Output Parameter:
340: . file - file pointer
342: Level: advanced
344: Notes:
345: For writable binary PetscViewers, the descriptor will only be valid for the
346: first processor in the communicator that shares the PetscViewer.
347:
348: Fortran Note:
349: This routine is not supported in Fortran.
351: Concepts: PetscViewerBinary^accessing info file
353: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
354: @*/
355: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
356: {
357: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
360: *file = vbinary->fdes_info;
361: return(0);
362: }
366: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
367: {
368: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
369: PetscErrorCode ierr;
370: PetscMPIInt rank;
371: int err;
374: MPI_Comm_rank(((PetscObject)v)->comm,&rank);
375: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
376: close(vbinary->fdes);
377: if (!rank && vbinary->storecompressed) {
378: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
379: FILE *fp;
380: /* compress the file */
381: PetscStrcpy(par,"gzip -f ");
382: PetscStrcat(par,vbinary->filename);
383: #if defined(PETSC_HAVE_POPEN)
384: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
385: if (fgets(buf,1024,fp)) {
386: SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
387: }
388: PetscPClose(PETSC_COMM_SELF,fp);
389: #else
390: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
391: #endif
392: }
393: }
394: if (vbinary->fdes_info) {
395: err = fclose(vbinary->fdes_info);
396: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
397: }
398: PetscStrfree(vbinary->filename);
399: PetscFree(vbinary);
400: return(0);
401: }
403: #if defined(PETSC_HAVE_MPIIO)
406: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
407: {
408: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
409: PetscErrorCode ierr;
410: int err;
413: if (vbinary->mfdes) {
414: MPI_File_close(&vbinary->mfdes);
415: }
416: if (vbinary->fdes_info) {
417: err = fclose(vbinary->fdes_info);
418: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
419: }
420: PetscStrfree(vbinary->filename);
421: PetscFree(vbinary);
422: return(0);
423: }
424: #endif
428: /*@
429: PetscViewerBinaryCreate - Create a binary viewer.
431: Collective on MPI_Comm
433: Input Parameters:
434: . comm - MPI communicator
436: Output Parameter:
437: . binv - PetscViewer for binary input/output
439: Level: beginner
440: @*/
441: PetscErrorCode PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
442: {
444:
446: PetscViewerCreate(comm,binv);
447: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
448: return(0);
449: }
453: /*@C
454: PetscViewerBinaryOpen - Opens a file for binary input/output.
456: Collective on MPI_Comm
458: Input Parameters:
459: + comm - MPI communicator
460: . name - name of file
461: - type - type of file
462: $ FILE_MODE_WRITE - create new file for binary output
463: $ FILE_MODE_READ - open existing file for binary input
464: $ FILE_MODE_APPEND - open existing file for binary output
466: Output Parameter:
467: . binv - PetscViewer for binary input/output to use with the specified file
469: Level: beginner
471: Note:
472: This PetscViewer should be destroyed with PetscViewerDestroy().
474: For reading files, the filename may begin with ftp:// or http:// and/or
475: end with .gz; in this case file is brought over and uncompressed.
477: For creating files, if the file name ends with .gz it is automatically
478: compressed when closed.
480: For writing files it only opens the file on processor 0 in the communicator.
481: For readable files it opens the file on all nodes that have the file. If
482: node 0 does not have the file it generates an error even if other nodes
483: do have the file.
485: Concepts: binary files
486: Concepts: PetscViewerBinary^creating
487: Concepts: gzip
488: Concepts: accessing remote file
489: Concepts: remote file
491: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
492: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
493: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
494: @*/
495: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
496: {
498:
500: PetscViewerCreate(comm,binv);
501: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
502: PetscViewerFileSetMode(*binv,type);
503: PetscViewerFileSetName(*binv,name);
504: return(0);
505: }
507: #if defined(PETSC_HAVE_MPIIO)
510: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth write)
511: {
512: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
513: PetscErrorCode ierr;
514: MPI_Datatype mdtype;
515: PetscMPIInt cnt = PetscMPIIntCast(count);
516: MPI_Status status;
517: MPI_Aint ul,dsize;
520: PetscDataTypeToMPIDataType(dtype,&mdtype);
521: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
522: if (write) {
523: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
524: } else {
525: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
526: }
527: MPI_Type_get_extent(mdtype,&ul,&dsize);
528: vbinary->moff += dsize*cnt;
529: return(0);
530: }
531: #endif
535: /*@C
536: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
538: Collective on MPI_Comm
540: Input Parameters:
541: + viewer - the binary viewer
542: . data - location to write the data
543: . count - number of items of data to read
544: - datatype - type of data to read
546: Level: beginner
548: Concepts: binary files
550: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
551: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
552: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
553: @*/
554: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
555: {
556: PetscErrorCode ierr;
557: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
559: #if defined(PETSC_HAVE_MPIIO)
560: if (vbinary->MPIIO) {
561: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
562: } else {
563: #endif
564: PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
565: #if defined(PETSC_HAVE_MPIIO)
566: }
567: #endif
568: return(0);
569: }
574: /*@C
575: PetscViewerBinaryWrite - writes to a binary file, only from the first process
577: Collective on MPI_Comm
579: Input Parameters:
580: + viewer - the binary viewer
581: . data - location of data
582: . count - number of items of data to read
583: . istemp - data may be overwritten
584: - datatype - type of data to read
586: Level: beginner
588: Notes: because byte-swapping may be done on the values in data it cannot be declared const
590: Concepts: binary files
592: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
593: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
594: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
595: @*/
596: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
597: {
598: PetscErrorCode ierr;
599: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
601: #if defined(PETSC_HAVE_MPIIO)
602: if (vbinary->MPIIO) {
603: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
604: } else {
605: #endif
606: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
607: #if defined(PETSC_HAVE_MPIIO)
608: }
609: #endif
610: return(0);
611: }
615: /*@C
616: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
618: Collective on MPI_Comm
620: Input Parameters:
621: + viewer - the binary viewer
622: - data - location of the array of strings
625: Level: intermediate
627: Concepts: binary files
629: Notes: array of strings is null terminated
631: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
632: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
633: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
634: @*/
635: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
636: {
637: PetscErrorCode ierr;
638: PetscInt i,n = 0,*sizes;
640: /* count number of strings */
641: while (data[n++]);
642: n--;
643: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
644: sizes[0] = n;
645: for (i=0; i<n; i++) {
646: size_t tmp;
647: PetscStrlen(data[i],&tmp);
648: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
649: }
650: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
651: for (i=0; i<n; i++) {
652: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
653: }
654: PetscFree(sizes);
655: return(0);
656: }
658: /*@C
659: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
661: Collective on MPI_Comm
663: Input Parameter:
664: . viewer - the binary viewer
666: Output Parameter:
667: . data - location of the array of strings
669: Level: intermediate
671: Concepts: binary files
673: Notes: array of strings is null terminated
675: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
676: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
677: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
678: @*/
679: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
680: {
681: PetscErrorCode ierr;
682: PetscInt i,n,*sizes,N = 0;
684: /* count number of strings */
685: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
686: PetscMalloc(n*sizeof(PetscInt),&sizes);
687: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
688: for (i=0; i<n; i++) {
689: N += sizes[i];
690: }
691: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
692: (*data)[0] = (char*)((*data) + n + 1);
693: for (i=1; i<n; i++) {
694: (*data)[i] = (*data)[i-1] + sizes[i-1];
695: }
696: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
697: (*data)[n] = 0;
698: PetscFree(sizes);
699: return(0);
700: }
704: /*@C
705: PetscViewerFileGetMode - Gets the type of file to be open
707: Collective on PetscViewer
709: Input Parameter:
710: . viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
712: Output Parameter:
713: . type - type of file
714: $ FILE_MODE_WRITE - create new file for binary output
715: $ FILE_MODE_READ - open existing file for binary input
716: $ FILE_MODE_APPEND - open existing file for binary output
718: Level: advanced
720: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
722: @*/
723: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
724: {
725: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);
730: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
731: if (f) {
732: (*f)(viewer,type);
733: }
734: return(0);
735: }
739: /*@
740: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
741: before PetscViewerFileSetName()
743: Collective on PetscViewer
745: Input Parameters:
746: . viewer - the PetscViewer; must be a binary
748: Notes: turns off the default usage of the .info file since that is not scalable
750: Level: advanced
752: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
754: @*/
755: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
756: {
757: PetscErrorCode ierr,(*f)(PetscViewer);
761: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
762: if (f) {
763: (*f)(viewer);
764: }
765: return(0);
766: }
769: /*@C
770: PetscViewerFileSetMode - Sets the type of file to be open
772: Collective on PetscViewer
774: Input Parameters:
775: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
776: - type - type of file
777: $ FILE_MODE_WRITE - create new file for binary output
778: $ FILE_MODE_READ - open existing file for binary input
779: $ FILE_MODE_APPEND - open existing file for binary output
781: Level: advanced
783: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
785: @*/
786: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
787: {
788: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);
792: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
793: if (f) {
794: (*f)(viewer,type);
795: }
796: return(0);
797: }
802: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
803: {
804: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
807: *type = vbinary->btype;
808: return(0);
809: }
815: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
816: {
817: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
820: vbinary->btype = type;
821: return(0);
822: }
825: /*
826: Actually opens the file
827: */
831: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
832: {
833: PetscMPIInt rank;
834: PetscErrorCode ierr;
835: size_t len;
836: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
837: const char *fname;
838: char bname[PETSC_MAX_PATH_LEN],*gz;
839: PetscTruth found;
840: PetscFileMode type = vbinary->btype;
843: if (type == (PetscFileMode) -1) {
844: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
845: }
846: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
847: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
849: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
851: /* copy name so we can edit it */
852: PetscStrallocpy(name,&vbinary->filename);
854: /* if ends in .gz strip that off and note user wants file compressed */
855: vbinary->storecompressed = PETSC_FALSE;
856: if (!rank && type == FILE_MODE_WRITE) {
857: /* remove .gz if it ends library name */
858: PetscStrstr(vbinary->filename,".gz",&gz);
859: if (gz) {
860: PetscStrlen(gz,&len);
861: if (len == 3) {
862: *gz = 0;
863: vbinary->storecompressed = PETSC_TRUE;
864: }
865: }
866: }
868: /* only first processor opens file if writeable */
869: if (!rank || type == FILE_MODE_READ) {
871: if (type == FILE_MODE_READ){
872: /* possibly get the file from remote site or compressed file */
873: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
874: fname = bname;
875: if (!rank && !found) {
876: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
877: } else if (!found) {
878: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
879: fname = 0;
880: }
881: } else {
882: fname = vbinary->filename;
883: }
885: #if defined(PETSC_HAVE_O_BINARY)
886: if (type == FILE_MODE_WRITE) {
887: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
888: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
889: }
890: } else if (type == FILE_MODE_READ && fname) {
891: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
892: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
893: }
894: } else if (type == FILE_MODE_APPEND) {
895: if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
896: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
897: }
898: } else if (fname) {
899: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
900: }
901: #else
902: if (type == FILE_MODE_WRITE) {
903: if ((vbinary->fdes = creat(fname,0666)) == -1) {
904: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
905: }
906: } else if (type == FILE_MODE_READ && fname) {
907: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
908: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
909: }
910: } else if (type == FILE_MODE_APPEND) {
911: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
912: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
913: }
914: } else if (fname) {
915: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
916: }
917: #endif
918: } else vbinary->fdes = -1;
919: viewer->format = PETSC_VIEWER_NOFORMAT;
921: /*
922: try to open info file: all processors open this file if read only
923: */
924: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
925: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
926:
927: PetscStrcpy(infoname,name);
928: /* remove .gz if it ends library name */
929: PetscStrstr(infoname,".gz",&gz);
930: if (gz) {
931: PetscStrlen(gz,&len);
932: if (len == 3) {
933: *gz = 0;
934: }
935: }
936:
937: PetscStrcat(infoname,".info");
938: PetscFixFilename(infoname,iname);
939: if (type == FILE_MODE_READ) {
940: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
941: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
942: } else {
943: vbinary->fdes_info = fopen(infoname,"w");
944: if (!vbinary->fdes_info) {
945: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
946: }
947: }
948: }
950: #if defined(PETSC_USE_LOG)
951: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
952: #endif
953: return(0);
954: }
957: #if defined(PETSC_HAVE_MPIIO)
961: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
962: {
963: PetscMPIInt rank;
964: PetscErrorCode ierr;
965: size_t len;
966: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
967: char *gz;
968: PetscTruth found;
969: PetscFileMode type = vbinary->btype;
972: if (type == (PetscFileMode) -1) {
973: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
974: }
975: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
976: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
978: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
979: PetscStrallocpy(name,&vbinary->filename);
980: vbinary->storecompressed = PETSC_FALSE;
983: /* only first processor opens file if writeable */
984: if (type == FILE_MODE_READ) {
985: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
986: } else if (type == FILE_MODE_WRITE) {
987: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
988: }
989: viewer->format = PETSC_VIEWER_NOFORMAT;
991: /*
992: try to open info file: all processors open this file if read only
994: Below is identical code to the code for Binary above, should be put in seperate routine
995: */
996: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
997: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
998:
999: PetscStrcpy(infoname,name);
1000: /* remove .gz if it ends library name */
1001: PetscStrstr(infoname,".gz",&gz);
1002: if (gz) {
1003: PetscStrlen(gz,&len);
1004: if (len == 3) {
1005: *gz = 0;
1006: }
1007: }
1008:
1009: PetscStrcat(infoname,".info");
1010: PetscFixFilename(infoname,iname);
1011: if (type == FILE_MODE_READ) {
1012: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1013: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1014: } else {
1015: vbinary->fdes_info = fopen(infoname,"w");
1016: if (!vbinary->fdes_info) {
1017: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1018: }
1019: }
1020: }
1022: #if defined(PETSC_USE_LOG)
1023: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1024: #endif
1025: return(0);
1026: }
1032: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer,PetscFileMode *type)
1033: {
1034: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1035: PetscErrorCode ierr;
1038: if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1039: viewer->ops->destroy = PetscViewerDestroy_Binary;
1040: vbinary->MPIIO = PETSC_TRUE;
1041: /* vbinary->skipinfo = PETSC_TRUE; */
1042: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1043: return(0);
1044: }
1046: #endif
1051: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1052: {
1053: PetscErrorCode ierr;
1054: PetscViewer_Binary *vbinary;
1055: #if defined(PETSC_HAVE_MPIIO)
1056: PetscTruth useMPIIO = PETSC_FALSE;
1057: #endif
1060: PetscNewLog(v,PetscViewer_Binary,&vbinary);
1061: v->data = (void*)vbinary;
1062: v->ops->destroy = PetscViewerDestroy_Binary;
1063: v->ops->flush = 0;
1064: v->iformat = 0;
1065: vbinary->fdes_info = 0;
1066: vbinary->fdes = 0;
1067: vbinary->skipinfo = PETSC_FALSE;
1068: vbinary->skipoptions = PETSC_TRUE;
1069: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1070: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1071: vbinary->btype = (PetscFileMode) -1;
1072: vbinary->storecompressed = PETSC_FALSE;
1073: vbinary->filename = 0;
1075: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1076: "PetscViewerFileSetName_Binary",
1077: PetscViewerFileSetName_Binary);
1078: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1079: "PetscViewerFileSetMode_Binary",
1080: PetscViewerFileSetMode_Binary);
1081: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1082: "PetscViewerFileGetMode_Binary",
1083: PetscViewerFileGetMode_Binary);
1084: #if defined(PETSC_HAVE_MPIIO)
1085: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1086: "PetscViewerBinarySetMPIIO_Binary",
1087: PetscViewerBinarySetMPIIO_Binary);
1088:
1089: PetscOptionsHasName(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO);
1090: if (useMPIIO) {
1091: PetscViewerBinarySetMPIIO(v);
1092: }
1093: #endif
1094: return(0);
1095: }
1099: /* ---------------------------------------------------------------------*/
1100: /*
1101: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1102: is attached to a communicator, in this case the attribute is a PetscViewer.
1103: */
1104: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1108: /*@C
1109: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1110: in a communicator.
1112: Collective on MPI_Comm
1114: Input Parameter:
1115: . comm - the MPI communicator to share the binary PetscViewer
1116:
1117: Level: intermediate
1119: Options Database Keys:
1120: $ -viewer_binary_filename <name>
1122: Environmental variables:
1123: - PETSC_VIEWER_BINARY_FILENAME
1125: Notes:
1126: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1127: an error code. The binary PetscViewer is usually used in the form
1128: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1130: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1131: PetscViewerDestroy()
1132: @*/
1133: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1134: {
1136: PetscTruth flg;
1137: PetscViewer viewer;
1138: char fname[PETSC_MAX_PATH_LEN];
1141: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1142: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1143: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1144: }
1145: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1146: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1147: if (!flg) { /* PetscViewer not yet created */
1148: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1149: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1150: if (!flg) {
1151: PetscStrcpy(fname,"binaryoutput");
1152: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1153: }
1154: PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1155: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1156: PetscObjectRegisterDestroy((PetscObject)viewer);
1157: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1158: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1159: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1160: }
1161: PetscFunctionReturn(viewer);
1162: }