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;
637: #if defined(PETSC_HAVE_MPIIO)
638: if (vbinary->MPIIO) {
639: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
640: } else {
641: #endif
642: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
643: #if defined(PETSC_HAVE_MPIIO)
644: }
645: #endif
646: return(0);
647: }
651: /*@C
652: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
654: Collective on MPI_Comm
656: Input Parameters:
657: + viewer - the binary viewer
658: - data - location of the array of strings
661: Level: intermediate
663: Concepts: binary files
665: Notes: array of strings is null terminated
667: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
668: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
669: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
670: @*/
671: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
672: {
673: PetscErrorCode ierr;
674: PetscInt i,n = 0,*sizes;
676: /* count number of strings */
677: while (data[n++]);
678: n--;
679: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
680: sizes[0] = n;
681: for (i=0; i<n; i++) {
682: size_t tmp;
683: PetscStrlen(data[i],&tmp);
684: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
685: }
686: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
687: for (i=0; i<n; i++) {
688: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
689: }
690: PetscFree(sizes);
691: return(0);
692: }
694: /*@C
695: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
697: Collective on MPI_Comm
699: Input Parameter:
700: . viewer - the binary viewer
702: Output Parameter:
703: . data - location of the array of strings
705: Level: intermediate
707: Concepts: binary files
709: Notes: array of strings is null terminated
711: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
712: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
713: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
714: @*/
715: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
716: {
717: PetscErrorCode ierr;
718: PetscInt i,n,*sizes,N = 0;
720: /* count number of strings */
721: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
722: PetscMalloc(n*sizeof(PetscInt),&sizes);
723: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
724: for (i=0; i<n; i++) {
725: N += sizes[i];
726: }
727: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
728: (*data)[0] = (char*)((*data) + n + 1);
729: for (i=1; i<n; i++) {
730: (*data)[i] = (*data)[i-1] + sizes[i-1];
731: }
732: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
733: (*data)[n] = 0;
734: PetscFree(sizes);
735: return(0);
736: }
740: /*@C
741: PetscViewerFileGetMode - Gets the type of file to be open
743: Collective on PetscViewer
745: Input Parameter:
746: . viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
748: Output Parameter:
749: . type - type of file
750: $ FILE_MODE_WRITE - create new file for binary output
751: $ FILE_MODE_READ - open existing file for binary input
752: $ FILE_MODE_APPEND - open existing file for binary output
754: Level: advanced
756: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
758: @*/
759: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
760: {
761: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);
766: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
767: if (f) {
768: (*f)(viewer,type);
769: }
770: return(0);
771: }
775: /*@
776: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
777: before PetscViewerFileSetName()
779: Collective on PetscViewer
781: Input Parameters:
782: . viewer - the PetscViewer; must be a binary
784: Notes: turns off the default usage of the .info file since that is not scalable
786: Level: advanced
788: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
790: @*/
791: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
792: {
793: PetscErrorCode ierr,(*f)(PetscViewer);
797: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
798: if (f) {
799: (*f)(viewer);
800: }
801: return(0);
802: }
805: /*@C
806: PetscViewerFileSetMode - Sets the type of file to be open
808: Collective on PetscViewer
810: Input Parameters:
811: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
812: - type - type of file
813: $ FILE_MODE_WRITE - create new file for binary output
814: $ FILE_MODE_READ - open existing file for binary input
815: $ FILE_MODE_APPEND - open existing file for binary output
817: Level: advanced
819: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
821: @*/
822: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
823: {
824: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);
828: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
829: if (f) {
830: (*f)(viewer,type);
831: }
832: return(0);
833: }
838: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
839: {
840: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
843: *type = vbinary->btype;
844: return(0);
845: }
851: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
852: {
853: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
856: vbinary->btype = type;
857: return(0);
858: }
861: /*
862: Actually opens the file
863: */
867: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
868: {
869: PetscMPIInt rank;
870: PetscErrorCode ierr;
871: size_t len;
872: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
873: const char *fname;
874: char bname[PETSC_MAX_PATH_LEN],*gz;
875: PetscTruth found;
876: PetscFileMode type = vbinary->btype;
879: if (type == (PetscFileMode) -1) {
880: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
881: }
882: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
883: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
885: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
887: /* copy name so we can edit it */
888: PetscStrallocpy(name,&vbinary->filename);
890: /* if ends in .gz strip that off and note user wants file compressed */
891: vbinary->storecompressed = PETSC_FALSE;
892: if (!rank && type == FILE_MODE_WRITE) {
893: /* remove .gz if it ends library name */
894: PetscStrstr(vbinary->filename,".gz",&gz);
895: if (gz) {
896: PetscStrlen(gz,&len);
897: if (len == 3) {
898: *gz = 0;
899: vbinary->storecompressed = PETSC_TRUE;
900: }
901: }
902: }
904: /* only first processor opens file if writeable */
905: if (!rank || type == FILE_MODE_READ) {
907: if (type == FILE_MODE_READ){
908: /* possibly get the file from remote site or compressed file */
909: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
910: fname = bname;
911: if (!rank && !found) {
912: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
913: } else if (!found) {
914: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
915: fname = 0;
916: }
917: } else {
918: fname = vbinary->filename;
919: }
921: #if defined(PETSC_HAVE_O_BINARY)
922: if (type == FILE_MODE_WRITE) {
923: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
924: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
925: }
926: } else if (type == FILE_MODE_READ && fname) {
927: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
928: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
929: }
930: } else if (type == FILE_MODE_APPEND) {
931: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
932: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
933: }
934: } else if (fname) {
935: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
936: }
937: #else
938: if (type == FILE_MODE_WRITE) {
939: if ((vbinary->fdes = creat(fname,0666)) == -1) {
940: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
941: }
942: } else if (type == FILE_MODE_READ && fname) {
943: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
944: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
945: }
946: } else if (type == FILE_MODE_APPEND) {
947: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
948: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
949: }
950: } else if (fname) {
951: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
952: }
953: #endif
954: } else vbinary->fdes = -1;
955: viewer->format = PETSC_VIEWER_NOFORMAT;
957: /*
958: try to open info file: all processors open this file if read only
959: */
960: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
961: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
962:
963: PetscStrcpy(infoname,name);
964: /* remove .gz if it ends library name */
965: PetscStrstr(infoname,".gz",&gz);
966: if (gz) {
967: PetscStrlen(gz,&len);
968: if (len == 3) {
969: *gz = 0;
970: }
971: }
972:
973: PetscStrcat(infoname,".info");
974: PetscFixFilename(infoname,iname);
975: if (type == FILE_MODE_READ) {
976: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
977: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
978: } else {
979: vbinary->fdes_info = fopen(infoname,"w");
980: if (!vbinary->fdes_info) {
981: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
982: }
983: }
984: }
986: #if defined(PETSC_USE_LOG)
987: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
988: #endif
989: return(0);
990: }
993: #if defined(PETSC_HAVE_MPIIO)
997: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
998: {
999: PetscMPIInt rank;
1000: PetscErrorCode ierr;
1001: size_t len;
1002: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1003: char *gz;
1004: PetscTruth found;
1005: PetscFileMode type = vbinary->btype;
1008: if (type == (PetscFileMode) -1) {
1009: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
1010: }
1011: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1012: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
1014: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1015: PetscStrallocpy(name,&vbinary->filename);
1016: vbinary->storecompressed = PETSC_FALSE;
1019: /* only first processor opens file if writeable */
1020: if (type == FILE_MODE_READ) {
1021: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1022: } else if (type == FILE_MODE_WRITE) {
1023: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1024: }
1025: viewer->format = PETSC_VIEWER_NOFORMAT;
1027: /*
1028: try to open info file: all processors open this file if read only
1030: Below is identical code to the code for Binary above, should be put in seperate routine
1031: */
1032: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1033: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1034:
1035: PetscStrcpy(infoname,name);
1036: /* remove .gz if it ends library name */
1037: PetscStrstr(infoname,".gz",&gz);
1038: if (gz) {
1039: PetscStrlen(gz,&len);
1040: if (len == 3) {
1041: *gz = 0;
1042: }
1043: }
1044:
1045: PetscStrcat(infoname,".info");
1046: PetscFixFilename(infoname,iname);
1047: if (type == FILE_MODE_READ) {
1048: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1049: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1050: } else {
1051: vbinary->fdes_info = fopen(infoname,"w");
1052: if (!vbinary->fdes_info) {
1053: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1054: }
1055: }
1056: }
1058: #if defined(PETSC_USE_LOG)
1059: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1060: #endif
1061: return(0);
1062: }
1068: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1069: {
1070: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1071: PetscErrorCode ierr;
1074: if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1075: viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1076: vbinary->MPIIO = PETSC_TRUE;
1077: /* vbinary->skipinfo = PETSC_TRUE; */
1078: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1079: return(0);
1080: }
1082: #endif
1087: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1088: {
1089: PetscErrorCode ierr;
1090: PetscViewer_Binary *vbinary;
1091: #if defined(PETSC_HAVE_MPIIO)
1092: PetscTruth useMPIIO = PETSC_FALSE;
1093: #endif
1096: PetscNewLog(v,PetscViewer_Binary,&vbinary);
1097: v->data = (void*)vbinary;
1098: v->ops->destroy = PetscViewerDestroy_Binary;
1099: v->ops->flush = 0;
1100: v->iformat = 0;
1101: vbinary->fdes_info = 0;
1102: vbinary->fdes = 0;
1103: vbinary->skipinfo = PETSC_FALSE;
1104: vbinary->skipoptions = PETSC_TRUE;
1105: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1106: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1107: vbinary->btype = (PetscFileMode) -1;
1108: vbinary->storecompressed = PETSC_FALSE;
1109: vbinary->filename = 0;
1110: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1112: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1113: "PetscViewerFileSetName_Binary",
1114: PetscViewerFileSetName_Binary);
1115: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1116: "PetscViewerFileSetMode_Binary",
1117: PetscViewerFileSetMode_Binary);
1118: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1119: "PetscViewerFileGetMode_Binary",
1120: PetscViewerFileGetMode_Binary);
1121: #if defined(PETSC_HAVE_MPIIO)
1122: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1123: "PetscViewerBinarySetMPIIO_Binary",
1124: PetscViewerBinarySetMPIIO_Binary);
1125:
1126: PetscOptionsGetTruth(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1127: if (useMPIIO) {
1128: PetscViewerBinarySetMPIIO(v);
1129: }
1130: #endif
1131: return(0);
1132: }
1136: /* ---------------------------------------------------------------------*/
1137: /*
1138: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1139: is attached to a communicator, in this case the attribute is a PetscViewer.
1140: */
1141: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1145: /*@C
1146: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1147: in a communicator.
1149: Collective on MPI_Comm
1151: Input Parameter:
1152: . comm - the MPI communicator to share the binary PetscViewer
1153:
1154: Level: intermediate
1156: Options Database Keys:
1157: + -viewer_binary_filename <name>
1158: . -viewer_binary_skip_info
1159: - -viewer_binary_skip_options
1161: Environmental variables:
1162: - PETSC_VIEWER_BINARY_FILENAME
1164: Notes:
1165: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1166: an error code. The binary PetscViewer is usually used in the form
1167: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1169: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1170: PetscViewerDestroy()
1171: @*/
1172: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1173: {
1175: PetscTruth flg;
1176: PetscViewer viewer;
1177: char fname[PETSC_MAX_PATH_LEN];
1180: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1181: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1182: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1183: }
1184: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1185: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1186: if (!flg) { /* PetscViewer not yet created */
1187: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1188: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1189: if (!flg) {
1190: PetscStrcpy(fname,"binaryoutput");
1191: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1192: }
1193: PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1194: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1195: PetscObjectRegisterDestroy((PetscObject)viewer);
1196: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1197: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1198: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1199: }
1200: PetscFunctionReturn(viewer);
1201: }