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 PetscViewerCreate()
244: Options Database Key:
245: . -viewer_binary_skip_info
247: Level: advanced
249: Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then
250: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
251: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().
253: The .info contains meta information about the data in the binary file, for example the block size if it was
254: set for a vector or matrix.
256: Concepts: PetscViewerBinary^accessing info file
258: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
259: PetscViewerBinaryGetSkipOptions()
260: @*/
261: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
262: {
263: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
266: vbinary->skipinfo = PETSC_TRUE;
267: return(0);
268: }
272: /*@
273: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
275: Not Collective
277: Input Parameters:
278: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
279: - skip - PETSC_TRUE means do not use
281: Options Database Key:
282: . -viewer_binary_skip_options
284: Level: advanced
286: Notes: This must be called after PetscViewerSetType()
288: Concepts: PetscViewerBinary^accessing info file
290: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
291: PetscViewerBinaryGetSkipOptions()
292: @*/
293: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
294: {
295: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
298: vbinary->skipoptions = skip;
299: return(0);
300: }
304: /*@
305: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
307: Not Collective
309: Input Parameter:
310: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
312: Output Parameter:
313: . skip - PETSC_TRUE means do not use
315: Level: advanced
317: Notes: This must be called after PetscViewerSetType()
319: Concepts: PetscViewerBinary^accessing info file
321: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
322: PetscViewerBinarySetSkipOptions()
323: @*/
324: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
325: {
326: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
329: *skip = vbinary->skipoptions;
330: return(0);
331: }
335: /*@C
336: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
337: info file associated with a binary file.
339: Not Collective
341: Input Parameter:
342: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
344: Output Parameter:
345: . file - file pointer
347: Level: advanced
349: Notes:
350: For writable binary PetscViewers, the descriptor will only be valid for the
351: first processor in the communicator that shares the PetscViewer.
352:
353: Fortran Note:
354: This routine is not supported in Fortran.
356: Concepts: PetscViewerBinary^accessing info file
358: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
359: @*/
360: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
361: {
362: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
365: *file = vbinary->fdes_info;
366: return(0);
367: }
371: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
372: {
373: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
374: PetscErrorCode ierr;
375: PetscMPIInt rank;
376: int err;
379: MPI_Comm_rank(((PetscObject)v)->comm,&rank);
380: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
381: close(vbinary->fdes);
382: if (!rank && vbinary->storecompressed) {
383: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
384: FILE *fp;
385: /* compress the file */
386: PetscStrcpy(par,"gzip -f ");
387: PetscStrcat(par,vbinary->filename);
388: #if defined(PETSC_HAVE_POPEN)
389: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
390: if (fgets(buf,1024,fp)) {
391: SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
392: }
393: PetscPClose(PETSC_COMM_SELF,fp);
394: #else
395: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
396: #endif
397: }
398: }
399: if (vbinary->fdes_info) {
400: err = fclose(vbinary->fdes_info);
401: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
402: }
403: PetscStrfree(vbinary->filename);
404: PetscFree(vbinary);
405: return(0);
406: }
408: #if defined(PETSC_HAVE_MPIIO)
411: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
412: {
413: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
414: PetscErrorCode ierr;
415: int err;
418: if (vbinary->mfdes) {
419: MPI_File_close(&vbinary->mfdes);
420: }
421: if (vbinary->fdes_info) {
422: err = fclose(vbinary->fdes_info);
423: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
424: }
425: PetscStrfree(vbinary->filename);
426: PetscFree(vbinary);
427: return(0);
428: }
429: #endif
433: /*@
434: PetscViewerBinaryCreate - Create a binary viewer.
436: Collective on MPI_Comm
438: Input Parameters:
439: . comm - MPI communicator
441: Output Parameter:
442: . binv - PetscViewer for binary input/output
444: Level: beginner
445: @*/
446: PetscErrorCode PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
447: {
449:
451: PetscViewerCreate(comm,binv);
452: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
453: return(0);
454: }
458: /*@C
459: PetscViewerBinaryOpen - Opens a file for binary input/output.
461: Collective on MPI_Comm
463: Input Parameters:
464: + comm - MPI communicator
465: . name - name of file
466: - type - type of file
467: $ FILE_MODE_WRITE - create new file for binary output
468: $ FILE_MODE_READ - open existing file for binary input
469: $ FILE_MODE_APPEND - open existing file for binary output
471: Output Parameter:
472: . binv - PetscViewer for binary input/output to use with the specified file
474: Level: beginner
476: Note:
477: This PetscViewer should be destroyed with PetscViewerDestroy().
479: For reading files, the filename may begin with ftp:// or http:// and/or
480: end with .gz; in this case file is brought over and uncompressed.
482: For creating files, if the file name ends with .gz it is automatically
483: compressed when closed.
485: For writing files it only opens the file on processor 0 in the communicator.
486: For readable files it opens the file on all nodes that have the file. If
487: node 0 does not have the file it generates an error even if other nodes
488: do have the file.
490: Concepts: binary files
491: Concepts: PetscViewerBinary^creating
492: Concepts: gzip
493: Concepts: accessing remote file
494: Concepts: remote file
496: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
497: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
498: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
499: @*/
500: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
501: {
503:
505: PetscViewerCreate(comm,binv);
506: PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
507: PetscViewerFileSetMode(*binv,type);
508: PetscViewerFileSetName(*binv,name);
509: return(0);
510: }
512: #if defined(PETSC_HAVE_MPIIO)
515: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth write)
516: {
517: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
518: PetscErrorCode ierr;
519: MPI_Datatype mdtype;
520: PetscMPIInt cnt = PetscMPIIntCast(count);
521: MPI_Status status;
522: MPI_Aint ul,dsize;
525: PetscDataTypeToMPIDataType(dtype,&mdtype);
526: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
527: if (write) {
528: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
529: } else {
530: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
531: }
532: MPI_Type_get_extent(mdtype,&ul,&dsize);
533: vbinary->moff += dsize*cnt;
534: return(0);
535: }
536: #endif
540: /*@C
541: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
543: Collective on MPI_Comm
545: Input Parameters:
546: + viewer - the binary viewer
547: . data - location to write the data
548: . count - number of items of data to read
549: - datatype - type of data to read
551: Level: beginner
553: Concepts: binary files
555: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
556: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
557: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
558: @*/
559: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
560: {
561: PetscErrorCode ierr;
562: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
564: #if defined(PETSC_HAVE_MPIIO)
565: if (vbinary->MPIIO) {
566: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
567: } else {
568: #endif
569: PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
570: #if defined(PETSC_HAVE_MPIIO)
571: }
572: #endif
573: return(0);
574: }
579: /*@C
580: PetscViewerBinaryWrite - writes to a binary file, only from the first process
582: Collective on MPI_Comm
584: Input Parameters:
585: + viewer - the binary viewer
586: . data - location of data
587: . count - number of items of data to read
588: . istemp - data may be overwritten
589: - datatype - type of data to read
591: Level: beginner
593: Notes: because byte-swapping may be done on the values in data it cannot be declared const
595: Concepts: binary files
597: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
598: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
599: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
600: @*/
601: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
602: {
603: PetscErrorCode ierr;
604: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
606: #if defined(PETSC_HAVE_MPIIO)
607: if (vbinary->MPIIO) {
608: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
609: } else {
610: #endif
611: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
612: #if defined(PETSC_HAVE_MPIIO)
613: }
614: #endif
615: return(0);
616: }
620: /*@C
621: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
623: Collective on MPI_Comm
625: Input Parameters:
626: + viewer - the binary viewer
627: - data - location of the array of strings
630: Level: intermediate
632: Concepts: binary files
634: Notes: array of strings is null terminated
636: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
637: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
638: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
639: @*/
640: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
641: {
642: PetscErrorCode ierr;
643: PetscInt i,n = 0,*sizes;
645: /* count number of strings */
646: while (data[n++]);
647: n--;
648: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
649: sizes[0] = n;
650: for (i=0; i<n; i++) {
651: size_t tmp;
652: PetscStrlen(data[i],&tmp);
653: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
654: }
655: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
656: for (i=0; i<n; i++) {
657: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
658: }
659: PetscFree(sizes);
660: return(0);
661: }
663: /*@C
664: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
666: Collective on MPI_Comm
668: Input Parameter:
669: . viewer - the binary viewer
671: Output Parameter:
672: . data - location of the array of strings
674: Level: intermediate
676: Concepts: binary files
678: Notes: array of strings is null terminated
680: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
681: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
682: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
683: @*/
684: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
685: {
686: PetscErrorCode ierr;
687: PetscInt i,n,*sizes,N = 0;
689: /* count number of strings */
690: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
691: PetscMalloc(n*sizeof(PetscInt),&sizes);
692: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
693: for (i=0; i<n; i++) {
694: N += sizes[i];
695: }
696: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
697: (*data)[0] = (char*)((*data) + n + 1);
698: for (i=1; i<n; i++) {
699: (*data)[i] = (*data)[i-1] + sizes[i-1];
700: }
701: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
702: (*data)[n] = 0;
703: PetscFree(sizes);
704: return(0);
705: }
709: /*@C
710: PetscViewerFileGetMode - Gets the type of file to be open
712: Collective on PetscViewer
714: Input Parameter:
715: . viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
717: Output Parameter:
718: . type - type of file
719: $ FILE_MODE_WRITE - create new file for binary output
720: $ FILE_MODE_READ - open existing file for binary input
721: $ FILE_MODE_APPEND - open existing file for binary output
723: Level: advanced
725: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
727: @*/
728: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
729: {
730: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);
735: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
736: if (f) {
737: (*f)(viewer,type);
738: }
739: return(0);
740: }
744: /*@
745: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
746: before PetscViewerFileSetName()
748: Collective on PetscViewer
750: Input Parameters:
751: . viewer - the PetscViewer; must be a binary
753: Notes: turns off the default usage of the .info file since that is not scalable
755: Level: advanced
757: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
759: @*/
760: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
761: {
762: PetscErrorCode ierr,(*f)(PetscViewer);
766: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
767: if (f) {
768: (*f)(viewer);
769: }
770: return(0);
771: }
774: /*@C
775: PetscViewerFileSetMode - Sets the type of file to be open
777: Collective on PetscViewer
779: Input Parameters:
780: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
781: - type - type of file
782: $ FILE_MODE_WRITE - create new file for binary output
783: $ FILE_MODE_READ - open existing file for binary input
784: $ FILE_MODE_APPEND - open existing file for binary output
786: Level: advanced
788: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
790: @*/
791: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
792: {
793: PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);
797: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
798: if (f) {
799: (*f)(viewer,type);
800: }
801: return(0);
802: }
807: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
808: {
809: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
812: *type = vbinary->btype;
813: return(0);
814: }
820: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
821: {
822: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
825: vbinary->btype = type;
826: return(0);
827: }
830: /*
831: Actually opens the file
832: */
836: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
837: {
838: PetscMPIInt rank;
839: PetscErrorCode ierr;
840: size_t len;
841: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
842: const char *fname;
843: char bname[PETSC_MAX_PATH_LEN],*gz;
844: PetscTruth found;
845: PetscFileMode type = vbinary->btype;
848: if (type == (PetscFileMode) -1) {
849: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
850: }
851: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
852: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
854: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
856: /* copy name so we can edit it */
857: PetscStrallocpy(name,&vbinary->filename);
859: /* if ends in .gz strip that off and note user wants file compressed */
860: vbinary->storecompressed = PETSC_FALSE;
861: if (!rank && type == FILE_MODE_WRITE) {
862: /* remove .gz if it ends library name */
863: PetscStrstr(vbinary->filename,".gz",&gz);
864: if (gz) {
865: PetscStrlen(gz,&len);
866: if (len == 3) {
867: *gz = 0;
868: vbinary->storecompressed = PETSC_TRUE;
869: }
870: }
871: }
873: /* only first processor opens file if writeable */
874: if (!rank || type == FILE_MODE_READ) {
876: if (type == FILE_MODE_READ){
877: /* possibly get the file from remote site or compressed file */
878: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
879: fname = bname;
880: if (!rank && !found) {
881: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
882: } else if (!found) {
883: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
884: fname = 0;
885: }
886: } else {
887: fname = vbinary->filename;
888: }
890: #if defined(PETSC_HAVE_O_BINARY)
891: if (type == FILE_MODE_WRITE) {
892: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
893: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
894: }
895: } else if (type == FILE_MODE_READ && fname) {
896: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
897: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
898: }
899: } else if (type == FILE_MODE_APPEND) {
900: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
901: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
902: }
903: } else if (fname) {
904: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
905: }
906: #else
907: if (type == FILE_MODE_WRITE) {
908: if ((vbinary->fdes = creat(fname,0666)) == -1) {
909: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
910: }
911: } else if (type == FILE_MODE_READ && fname) {
912: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
913: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
914: }
915: } else if (type == FILE_MODE_APPEND) {
916: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
917: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
918: }
919: } else if (fname) {
920: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
921: }
922: #endif
923: } else vbinary->fdes = -1;
924: viewer->format = PETSC_VIEWER_NOFORMAT;
926: /*
927: try to open info file: all processors open this file if read only
928: */
929: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
930: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
931:
932: PetscStrcpy(infoname,name);
933: /* remove .gz if it ends library name */
934: PetscStrstr(infoname,".gz",&gz);
935: if (gz) {
936: PetscStrlen(gz,&len);
937: if (len == 3) {
938: *gz = 0;
939: }
940: }
941:
942: PetscStrcat(infoname,".info");
943: PetscFixFilename(infoname,iname);
944: if (type == FILE_MODE_READ) {
945: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
946: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
947: } else {
948: vbinary->fdes_info = fopen(infoname,"w");
949: if (!vbinary->fdes_info) {
950: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
951: }
952: }
953: }
955: #if defined(PETSC_USE_LOG)
956: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
957: #endif
958: return(0);
959: }
962: #if defined(PETSC_HAVE_MPIIO)
966: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
967: {
968: PetscMPIInt rank;
969: PetscErrorCode ierr;
970: size_t len;
971: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
972: char *gz;
973: PetscTruth found;
974: PetscFileMode type = vbinary->btype;
977: if (type == (PetscFileMode) -1) {
978: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
979: }
980: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
981: PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
983: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
984: PetscStrallocpy(name,&vbinary->filename);
985: vbinary->storecompressed = PETSC_FALSE;
988: /* only first processor opens file if writeable */
989: if (type == FILE_MODE_READ) {
990: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
991: } else if (type == FILE_MODE_WRITE) {
992: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
993: }
994: viewer->format = PETSC_VIEWER_NOFORMAT;
996: /*
997: try to open info file: all processors open this file if read only
999: Below is identical code to the code for Binary above, should be put in seperate routine
1000: */
1001: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1002: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1003:
1004: PetscStrcpy(infoname,name);
1005: /* remove .gz if it ends library name */
1006: PetscStrstr(infoname,".gz",&gz);
1007: if (gz) {
1008: PetscStrlen(gz,&len);
1009: if (len == 3) {
1010: *gz = 0;
1011: }
1012: }
1013:
1014: PetscStrcat(infoname,".info");
1015: PetscFixFilename(infoname,iname);
1016: if (type == FILE_MODE_READ) {
1017: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1018: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1019: } else {
1020: vbinary->fdes_info = fopen(infoname,"w");
1021: if (!vbinary->fdes_info) {
1022: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1023: }
1024: }
1025: }
1027: #if defined(PETSC_USE_LOG)
1028: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1029: #endif
1030: return(0);
1031: }
1037: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer,PetscFileMode *type)
1038: {
1039: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1040: PetscErrorCode ierr;
1043: if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1044: viewer->ops->destroy = PetscViewerDestroy_Binary;
1045: vbinary->MPIIO = PETSC_TRUE;
1046: /* vbinary->skipinfo = PETSC_TRUE; */
1047: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1048: return(0);
1049: }
1051: #endif
1056: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1057: {
1058: PetscErrorCode ierr;
1059: PetscViewer_Binary *vbinary;
1060: #if defined(PETSC_HAVE_MPIIO)
1061: PetscTruth useMPIIO = PETSC_FALSE;
1062: #endif
1065: PetscNewLog(v,PetscViewer_Binary,&vbinary);
1066: v->data = (void*)vbinary;
1067: v->ops->destroy = PetscViewerDestroy_Binary;
1068: v->ops->flush = 0;
1069: v->iformat = 0;
1070: vbinary->fdes_info = 0;
1071: vbinary->fdes = 0;
1072: vbinary->skipinfo = PETSC_FALSE;
1073: vbinary->skipoptions = PETSC_TRUE;
1074: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1075: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1076: vbinary->btype = (PetscFileMode) -1;
1077: vbinary->storecompressed = PETSC_FALSE;
1078: vbinary->filename = 0;
1080: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1081: "PetscViewerFileSetName_Binary",
1082: PetscViewerFileSetName_Binary);
1083: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1084: "PetscViewerFileSetMode_Binary",
1085: PetscViewerFileSetMode_Binary);
1086: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1087: "PetscViewerFileGetMode_Binary",
1088: PetscViewerFileGetMode_Binary);
1089: #if defined(PETSC_HAVE_MPIIO)
1090: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1091: "PetscViewerBinarySetMPIIO_Binary",
1092: PetscViewerBinarySetMPIIO_Binary);
1093:
1094: PetscOptionsHasName(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO);
1095: if (useMPIIO) {
1096: PetscViewerBinarySetMPIIO(v);
1097: }
1098: #endif
1099: return(0);
1100: }
1104: /* ---------------------------------------------------------------------*/
1105: /*
1106: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1107: is attached to a communicator, in this case the attribute is a PetscViewer.
1108: */
1109: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1113: /*@C
1114: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1115: in a communicator.
1117: Collective on MPI_Comm
1119: Input Parameter:
1120: . comm - the MPI communicator to share the binary PetscViewer
1121:
1122: Level: intermediate
1124: Options Database Keys:
1125: $ -viewer_binary_filename <name>
1127: Environmental variables:
1128: - PETSC_VIEWER_BINARY_FILENAME
1130: Notes:
1131: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1132: an error code. The binary PetscViewer is usually used in the form
1133: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1135: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1136: PetscViewerDestroy()
1137: @*/
1138: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1139: {
1141: PetscTruth flg;
1142: PetscViewer viewer;
1143: char fname[PETSC_MAX_PATH_LEN];
1146: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1147: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1148: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1149: }
1150: MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1151: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1152: if (!flg) { /* PetscViewer not yet created */
1153: PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1154: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1155: if (!flg) {
1156: PetscStrcpy(fname,"binaryoutput");
1157: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1158: }
1159: PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1160: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1161: PetscObjectRegisterDestroy((PetscObject)viewer);
1162: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1163: MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1164: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1165: }
1166: PetscFunctionReturn(viewer);
1167: }