Actual source code: binv.c
1: #define PETSC_DLL
2: #include private/viewerimpl.h
3: #include <fcntl.h>
4: #if defined(PETSC_HAVE_UNISTD_H)
5: #include <unistd.h>
6: #endif
7: #if defined (PETSC_HAVE_IO_H)
8: #include <io.h>
9: #endif
11: typedef struct {
12: int fdes; /* file descriptor, ignored if using MPI IO */
13: #if defined(PETSC_HAVE_MPIIO)
14: PetscTruth 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: PetscTruth storecompressed; /* gzip the write binary file when closing it*/
21: char *filename;
22: PetscTruth skipinfo; /* Don't create info file for writing; don't use for reading */
23: PetscTruth skipoptions; /* don't use PETSc options database when loading */
24: PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
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: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
201: Not Collective
203: Input Parameter:
204: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
206: Output Parameter:
207: . fc - the number of messages
209: Level: advanced
211: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
213: @*/
214: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
215: {
216: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
219: *fc = vbinary->flowcontrol;
220: return(0);
221: }
225: /*@C
226: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
228: Not Collective
230: Input Parameter:
231: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
233: Output Parameter:
234: . fdes - file descriptor
236: Level: advanced
238: Notes:
239: For writable binary PetscViewers, the descriptor will only be valid for the
240: first processor in the communicator that shares the PetscViewer. For readable
241: files it will only be valid on nodes that have the file. If node 0 does not
242: have the file it generates an error even if another node does have the file.
243:
244: Fortran Note:
245: This routine is not supported in Fortran.
247: Concepts: file descriptor^getting
248: Concepts: PetscViewerBinary^accessing file descriptor
250: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
251: @*/
252: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
253: {
254: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
257: *fdes = vbinary->fdes;
258: return(0);
259: }
263: /*@
264: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
266: Not Collective
268: Input Paramter:
269: . viewer - PetscViewer context, obtained from PetscViewerCreate()
271: Options Database Key:
272: . -viewer_binary_skip_info
274: Level: advanced
276: Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then
277: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
278: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().
280: The .info contains meta information about the data in the binary file, for example the block size if it was
281: set for a vector or matrix.
283: Concepts: PetscViewerBinary^accessing info file
285: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
286: PetscViewerBinaryGetSkipOptions()
287: @*/
288: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
289: {
290: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
293: vbinary->skipinfo = PETSC_TRUE;
294: return(0);
295: }
299: /*@
300: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
302: Not Collective
304: Input Parameters:
305: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
306: - skip - PETSC_TRUE means do not use
308: Options Database Key:
309: . -viewer_binary_skip_options
311: Level: advanced
313: Notes: This must be called after PetscViewerSetType()
315: Concepts: PetscViewerBinary^accessing info file
317: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
318: PetscViewerBinaryGetSkipOptions()
319: @*/
320: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
321: {
322: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
325: vbinary->skipoptions = skip;
326: return(0);
327: }
331: /*@
332: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
334: Not Collective
336: Input Parameter:
337: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
339: Output Parameter:
340: . skip - PETSC_TRUE means do not use
342: Level: advanced
344: Notes: This must be called after PetscViewerSetType()
346: Concepts: PetscViewerBinary^accessing info file
348: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
349: PetscViewerBinarySetSkipOptions()
350: @*/
351: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
352: {
353: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
356: *skip = vbinary->skipoptions;
357: return(0);
358: }
362: /*@C
363: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
364: info file associated with a binary file.
366: Not Collective
368: Input Parameter:
369: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
371: Output Parameter:
372: . file - file pointer
374: Level: advanced
376: Notes:
377: For writable binary PetscViewers, the descriptor will only be valid for the
378: first processor in the communicator that shares the PetscViewer.
379:
380: Fortran Note:
381: This routine is not supported in Fortran.
383: Concepts: PetscViewerBinary^accessing info file
385: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
386: @*/
387: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
388: {
389: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
392: *file = vbinary->fdes_info;
393: return(0);
394: }
398: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
399: {
400: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
401: PetscErrorCode ierr;
402: PetscMPIInt rank;
403: int err;
406: MPI_Comm_rank(((PetscObject)v)->comm,&rank);
407: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
408: close(vbinary->fdes);
409: if (!rank && vbinary->storecompressed) {
410: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
411: FILE *fp;
412: /* compress the file */
413: PetscStrcpy(par,"gzip -f ");
414: PetscStrcat(par,vbinary->filename);
415: #if defined(PETSC_HAVE_POPEN)
416: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
417: if (fgets(buf,1024,fp)) {
418: SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
419: }
420: PetscPClose(PETSC_COMM_SELF,fp);
421: #else
422: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
423: #endif
424: }
425: }
426: if (vbinary->fdes_info) {
427: err = fclose(vbinary->fdes_info);
428: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
429: }
430: PetscStrfree(vbinary->filename);
431: PetscFree(vbinary);
432: return(0);
433: }
435: #if defined(PETSC_HAVE_MPIIO)
438: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
439: {
440: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
441: PetscErrorCode ierr;
442: int err;
445: if (vbinary->mfdes) {
446: MPI_File_close(&vbinary->mfdes);
447: }
448: if (vbinary->fdes_info) {
449: err = fclose(vbinary->fdes_info);
450: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
451: }
452: PetscStrfree(vbinary->filename);
453: PetscFree(vbinary);
454: return(0);
455: }
456: #endif
460: /*@
461: PetscViewerBinaryCreate - Create a binary viewer.
463: Collective on MPI_Comm
465: Input Parameters:
466: . comm - MPI communicator
468: Output Parameter:
469: . binv - PetscViewer for binary input/output
471: Level: beginner
472: @*/
473: PetscErrorCode PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
474: {
476:
478: PetscViewerCreate(comm,binv);
479: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
480: return(0);
481: }
485: /*@C
486: PetscViewerBinaryOpen - Opens a file for binary input/output.
488: Collective on MPI_Comm
490: Input Parameters:
491: + comm - MPI communicator
492: . name - name of file
493: - type - type of file
494: $ FILE_MODE_WRITE - create new file for binary output
495: $ FILE_MODE_READ - open existing file for binary input
496: $ FILE_MODE_APPEND - open existing file for binary output
498: Output Parameter:
499: . binv - PetscViewer for binary input/output to use with the specified file
501: Options Database Keys:
502: + -viewer_binary_skip_info
503: - -viewer_binary_skip_options
505: Level: beginner
507: Note:
508: This PetscViewer should be destroyed with PetscViewerDestroy().
510: For reading files, the filename may begin with ftp:// or http:// and/or
511: end with .gz; in this case file is brought over and uncompressed.
513: For creating files, if the file name ends with .gz it is automatically
514: compressed when closed.
516: For writing files it only opens the file on processor 0 in the communicator.
517: For readable files it opens the file on all nodes that have the file. If
518: node 0 does not have the file it generates an error even if other nodes
519: do have the file.
521: Concepts: binary files
522: Concepts: PetscViewerBinary^creating
523: Concepts: gzip
524: Concepts: accessing remote file
525: Concepts: remote file
527: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
528: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
529: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
530: @*/
531: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
532: {
534:
536: PetscViewerCreate(comm,binv);
537: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
538: PetscViewerFileSetMode(*binv,type);
539: PetscViewerFileSetName(*binv,name);
540: return(0);
541: }
543: #if defined(PETSC_HAVE_MPIIO)
546: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth write)
547: {
548: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
549: PetscErrorCode ierr;
550: MPI_Datatype mdtype;
551: PetscMPIInt cnt = PetscMPIIntCast(count);
552: MPI_Status status;
553: MPI_Aint ul,dsize;
556: PetscDataTypeToMPIDataType(dtype,&mdtype);
557: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
558: if (write) {
559: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
560: } else {
561: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
562: }
563: MPI_Type_get_extent(mdtype,&ul,&dsize);
564: vbinary->moff += dsize*cnt;
565: return(0);
566: }
567: #endif
571: /*@C
572: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
574: Collective on MPI_Comm
576: Input Parameters:
577: + viewer - the binary viewer
578: . data - location to write the data
579: . count - number of items of data to read
580: - datatype - type of data to read
582: Level: beginner
584: Concepts: binary files
586: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
587: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
588: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
589: @*/
590: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
591: {
592: PetscErrorCode ierr;
593: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
595: #if defined(PETSC_HAVE_MPIIO)
596: if (vbinary->MPIIO) {
597: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
598: } else {
599: #endif
600: PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
601: #if defined(PETSC_HAVE_MPIIO)
602: }
603: #endif
604: return(0);
605: }
610: /*@C
611: PetscViewerBinaryWrite - writes to a binary file, only from the first process
613: Collective on MPI_Comm
615: Input Parameters:
616: + viewer - the binary viewer
617: . data - location of data
618: . count - number of items of data to read
619: . istemp - data may be overwritten
620: - datatype - type of data to read
622: Level: beginner
624: Notes: because byte-swapping may be done on the values in data it cannot be declared const
626: Concepts: binary files
628: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
629: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
630: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
631: @*/
632: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
633: {
634: PetscErrorCode ierr;
635: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
638: #if defined(PETSC_HAVE_MPIIO)
639: if (vbinary->MPIIO) {
640: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
641: } else {
642: #endif
643: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
644: #if defined(PETSC_HAVE_MPIIO)
645: }
646: #endif
647: return(0);
648: }
652: /*@C
653: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
655: Collective on MPI_Comm
657: Input Parameters:
658: + viewer - the binary viewer
659: - data - location of the array of strings
662: Level: intermediate
664: Concepts: binary files
666: Notes: array of strings is null terminated
668: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
669: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
670: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
671: @*/
672: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
673: {
674: PetscErrorCode ierr;
675: PetscInt i,n = 0,*sizes;
677: /* count number of strings */
678: while (data[n++]);
679: n--;
680: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
681: sizes[0] = n;
682: for (i=0; i<n; i++) {
683: size_t tmp;
684: PetscStrlen(data[i],&tmp);
685: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
686: }
687: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
688: for (i=0; i<n; i++) {
689: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
690: }
691: PetscFree(sizes);
692: return(0);
693: }
695: /*@C
696: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
698: Collective on MPI_Comm
700: Input Parameter:
701: . viewer - the binary viewer
703: Output Parameter:
704: . data - location of the array of strings
706: Level: intermediate
708: Concepts: binary files
710: Notes: array of strings is null terminated
712: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
713: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
714: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
715: @*/
716: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
717: {
718: PetscErrorCode ierr;
719: PetscInt i,n,*sizes,N = 0;
721: /* count number of strings */
722: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
723: PetscMalloc(n*sizeof(PetscInt),&sizes);
724: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
725: for (i=0; i<n; i++) {
726: N += sizes[i];
727: }
728: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
729: (*data)[0] = (char*)((*data) + n + 1);
730: for (i=1; i<n; i++) {
731: (*data)[i] = (*data)[i-1] + sizes[i-1];
732: }
733: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
734: (*data)[n] = 0;
735: PetscFree(sizes);
736: return(0);
737: }
741: /*@C
742: PetscViewerFileGetMode - Gets the type of file to be open
744: Collective on PetscViewer
746: Input Parameter:
747: . viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
749: Output Parameter:
750: . type - type of file
751: $ FILE_MODE_WRITE - create new file for binary output
752: $ FILE_MODE_READ - open existing file for binary input
753: $ FILE_MODE_APPEND - open existing file for binary output
755: Level: advanced
757: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
759: @*/
760: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
761: {
762: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);
767: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
768: if (f) {
769: (*f)(viewer,type);
770: }
771: return(0);
772: }
776: /*@
777: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
778: before PetscViewerFileSetName()
780: Collective on PetscViewer
782: Input Parameters:
783: . viewer - the PetscViewer; must be a binary
785: Notes: turns off the default usage of the .info file since that is not scalable
787: Level: advanced
789: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
791: @*/
792: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
793: {
794: PetscErrorCode ierr,(*f)(PetscViewer);
798: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
799: if (f) {
800: (*f)(viewer);
801: }
802: return(0);
803: }
806: /*@C
807: PetscViewerFileSetMode - Sets the type of file to be open
809: Collective on PetscViewer
811: Input Parameters:
812: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
813: - type - type of file
814: $ FILE_MODE_WRITE - create new file for binary output
815: $ FILE_MODE_READ - open existing file for binary input
816: $ FILE_MODE_APPEND - open existing file for binary output
818: Level: advanced
820: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
822: @*/
823: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
824: {
825: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);
829: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
830: if (f) {
831: (*f)(viewer,type);
832: }
833: return(0);
834: }
839: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
840: {
841: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
844: *type = vbinary->btype;
845: return(0);
846: }
852: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
853: {
854: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
857: vbinary->btype = type;
858: return(0);
859: }
862: /*
863: Actually opens the file
864: */
868: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
869: {
870: PetscMPIInt rank;
871: PetscErrorCode ierr;
872: size_t len;
873: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
874: const char *fname;
875: char bname[PETSC_MAX_PATH_LEN],*gz;
876: PetscTruth found;
877: PetscFileMode type = vbinary->btype;
880: if (type == (PetscFileMode) -1) {
881: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
882: }
883: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
884: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
886: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
888: /* copy name so we can edit it */
889: PetscStrallocpy(name,&vbinary->filename);
891: /* if ends in .gz strip that off and note user wants file compressed */
892: vbinary->storecompressed = PETSC_FALSE;
893: if (!rank && type == FILE_MODE_WRITE) {
894: /* remove .gz if it ends library name */
895: PetscStrstr(vbinary->filename,".gz",&gz);
896: if (gz) {
897: PetscStrlen(gz,&len);
898: if (len == 3) {
899: *gz = 0;
900: vbinary->storecompressed = PETSC_TRUE;
901: }
902: }
903: }
905: /* only first processor opens file if writeable */
906: if (!rank || type == FILE_MODE_READ) {
908: if (type == FILE_MODE_READ){
909: /* possibly get the file from remote site or compressed file */
910: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
911: fname = bname;
912: if (!rank && !found) {
913: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
914: } else if (!found) {
915: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
916: fname = 0;
917: }
918: } else {
919: fname = vbinary->filename;
920: }
922: #if defined(PETSC_HAVE_O_BINARY)
923: if (type == FILE_MODE_WRITE) {
924: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
925: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
926: }
927: } else if (type == FILE_MODE_READ && fname) {
928: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
929: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
930: }
931: } else if (type == FILE_MODE_APPEND) {
932: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
933: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
934: }
935: } else if (fname) {
936: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
937: }
938: #else
939: if (type == FILE_MODE_WRITE) {
940: if ((vbinary->fdes = creat(fname,0666)) == -1) {
941: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
942: }
943: } else if (type == FILE_MODE_READ && fname) {
944: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
945: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
946: }
947: } else if (type == FILE_MODE_APPEND) {
948: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
949: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
950: }
951: } else if (fname) {
952: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
953: }
954: #endif
955: } else vbinary->fdes = -1;
956: viewer->format = PETSC_VIEWER_NOFORMAT;
958: /*
959: try to open info file: all processors open this file if read only
960: */
961: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
962: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
963:
964: PetscStrcpy(infoname,name);
965: /* remove .gz if it ends library name */
966: PetscStrstr(infoname,".gz",&gz);
967: if (gz) {
968: PetscStrlen(gz,&len);
969: if (len == 3) {
970: *gz = 0;
971: }
972: }
973:
974: PetscStrcat(infoname,".info");
975: PetscFixFilename(infoname,iname);
976: if (type == FILE_MODE_READ) {
977: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
978: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
979: } else {
980: vbinary->fdes_info = fopen(infoname,"w");
981: if (!vbinary->fdes_info) {
982: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
983: }
984: }
985: }
987: #if defined(PETSC_USE_LOG)
988: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
989: #endif
990: return(0);
991: }
994: #if defined(PETSC_HAVE_MPIIO)
998: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
999: {
1000: PetscMPIInt rank;
1001: PetscErrorCode ierr;
1002: size_t len;
1003: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1004: char *gz;
1005: PetscTruth found;
1006: PetscFileMode type = vbinary->btype;
1009: if (type == (PetscFileMode) -1) {
1010: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
1011: }
1012: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1013: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
1015: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1016: PetscStrallocpy(name,&vbinary->filename);
1017: vbinary->storecompressed = PETSC_FALSE;
1020: /* only first processor opens file if writeable */
1021: if (type == FILE_MODE_READ) {
1022: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1023: } else if (type == FILE_MODE_WRITE) {
1024: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1025: }
1026: viewer->format = PETSC_VIEWER_NOFORMAT;
1028: /*
1029: try to open info file: all processors open this file if read only
1031: Below is identical code to the code for Binary above, should be put in seperate routine
1032: */
1033: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1034: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1035:
1036: PetscStrcpy(infoname,name);
1037: /* remove .gz if it ends library name */
1038: PetscStrstr(infoname,".gz",&gz);
1039: if (gz) {
1040: PetscStrlen(gz,&len);
1041: if (len == 3) {
1042: *gz = 0;
1043: }
1044: }
1045:
1046: PetscStrcat(infoname,".info");
1047: PetscFixFilename(infoname,iname);
1048: if (type == FILE_MODE_READ) {
1049: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1050: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1051: } else {
1052: vbinary->fdes_info = fopen(infoname,"w");
1053: if (!vbinary->fdes_info) {
1054: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1055: }
1056: }
1057: }
1059: #if defined(PETSC_USE_LOG)
1060: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1061: #endif
1062: return(0);
1063: }
1069: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1070: {
1071: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1072: PetscErrorCode ierr;
1075: if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1076: viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1077: vbinary->MPIIO = PETSC_TRUE;
1078: /* vbinary->skipinfo = PETSC_TRUE; */
1079: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1080: return(0);
1081: }
1083: #endif
1088: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1089: {
1090: PetscErrorCode ierr;
1091: PetscViewer_Binary *vbinary;
1092: #if defined(PETSC_HAVE_MPIIO)
1093: PetscTruth useMPIIO = PETSC_FALSE;
1094: #endif
1097: PetscNewLog(v,PetscViewer_Binary,&vbinary);
1098: v->data = (void*)vbinary;
1099: v->ops->destroy = PetscViewerDestroy_Binary;
1100: v->ops->flush = 0;
1101: v->iformat = 0;
1102: vbinary->fdes_info = 0;
1103: vbinary->fdes = 0;
1104: vbinary->skipinfo = PETSC_FALSE;
1105: vbinary->skipoptions = PETSC_TRUE;
1106: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1107: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1108: vbinary->btype = (PetscFileMode) -1;
1109: vbinary->storecompressed = PETSC_FALSE;
1110: vbinary->filename = 0;
1111: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1113: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1114: "PetscViewerFileSetName_Binary",
1115: PetscViewerFileSetName_Binary);
1116: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1117: "PetscViewerFileSetMode_Binary",
1118: PetscViewerFileSetMode_Binary);
1119: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1120: "PetscViewerFileGetMode_Binary",
1121: PetscViewerFileGetMode_Binary);
1122: #if defined(PETSC_HAVE_MPIIO)
1123: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1124: "PetscViewerBinarySetMPIIO_Binary",
1125: PetscViewerBinarySetMPIIO_Binary);
1126:
1127: PetscOptionsGetTruth(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1128: if (useMPIIO) {
1129: PetscViewerBinarySetMPIIO(v);
1130: }
1131: #endif
1132: return(0);
1133: }
1137: /* ---------------------------------------------------------------------*/
1138: /*
1139: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1140: is attached to a communicator, in this case the attribute is a PetscViewer.
1141: */
1142: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1146: /*@C
1147: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1148: in a communicator.
1150: Collective on MPI_Comm
1152: Input Parameter:
1153: . comm - the MPI communicator to share the binary PetscViewer
1154:
1155: Level: intermediate
1157: Options Database Keys:
1158: + -viewer_binary_filename <name>
1159: . -viewer_binary_skip_info
1160: - -viewer_binary_skip_options
1162: Environmental variables:
1163: - PETSC_VIEWER_BINARY_FILENAME
1165: Notes:
1166: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1167: an error code. The binary PetscViewer is usually used in the form
1168: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1170: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1171: PetscViewerDestroy()
1172: @*/
1173: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1174: {
1176: PetscTruth flg;
1177: PetscViewer viewer;
1178: char fname[PETSC_MAX_PATH_LEN];
1181: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1182: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1183: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1184: }
1185: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1186: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1187: if (!flg) { /* PetscViewer not yet created */
1188: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1189: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1190: if (!flg) {
1191: PetscStrcpy(fname,"binaryoutput");
1192: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1193: }
1194: PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1195: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1196: PetscObjectRegisterDestroy((PetscObject)viewer);
1197: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1198: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1199: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1200: }
1201: PetscFunctionReturn(viewer);
1202: }