Actual source code: binv.c
2: #include <private/viewerimpl.h> /*I "petscsys.h" I*/
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: PetscBool 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: PetscBool storecompressed; /* gzip the write binary file when closing it*/
21: char *filename;
22: PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */
23: PetscBool skipoptions; /* don't use PETSc options database when loading */
24: PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
25: PetscBool skipheader; /* don't write header, only raw data */
26: } PetscViewer_Binary;
30: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
31: {
32: int rank;
33: PetscErrorCode ierr;
34: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
37: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
38: if (!rank) {
39: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
40: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
41: obinary = (PetscViewer_Binary*)(*outviewer)->data;
42: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
43: } else {
44: *outviewer = 0;
45: }
46: return(0);
47: }
51: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
52: {
54: PetscErrorCode rank;
57: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
58: if (!rank) {
59: PetscFree((*outviewer)->data);
60: PetscHeaderDestroy(outviewer);
61: }
62: return(0);
63: }
65: #if defined(PETSC_HAVE_MPIIO)
68: /*@C
69: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
71: Not Collective
73: Input Parameter:
74: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
76: Output Parameter:
77: . off - the current offset
79: Level: advanced
81: Fortran Note:
82: This routine is not supported in Fortran.
84: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
86: Concepts: file descriptor^getting
87: Concepts: PetscViewerBinary^accessing file descriptor
89: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
90: @*/
91: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
92: {
93: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
96: *off = vbinary->moff;
97: return(0);
98: }
102: /*@C
103: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
105: Not Collective
107: Input Parameters:
108: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
109: - off - the addition to the offset
111: Level: advanced
113: Fortran Note:
114: This routine is not supported in Fortran.
116: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
118: Concepts: file descriptor^getting
119: Concepts: PetscViewerBinary^accessing file descriptor
121: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
122: @*/
123: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
124: {
125: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
128: vbinary->moff += off;
129: return(0);
130: }
134: /*@C
135: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
137: Not Collective
139: Input Parameter:
140: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
142: Output Parameter:
143: . fdes - file descriptor
145: Level: advanced
147: Fortran Note:
148: This routine is not supported in Fortran.
150: Concepts: file descriptor^getting
151: Concepts: PetscViewerBinary^accessing file descriptor
153: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
154: @*/
155: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
156: {
157: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
160: *fdes = vbinary->mfdes;
161: return(0);
162: }
166: /*@C
167: PetscViewerBinaryGetMPIIO - Returns PETSC_TRUE if the binary viewer is an MPI viewer.
169: Not Collective
171: Input Parameter:
172: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
174: Output Parameter:
175: - flg - PETSC_TRUE if MPI IO is being used
177: Options Database:
178: -viewer_binary_mpiio : Flag for using MPI-IO
180: Level: advanced
182: Fortran Note:
183: This routine is not supported in Fortran.
185: Concepts: file descriptor^getting
186: Concepts: PetscViewerBinary^accessing file descriptor
188: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
189: @*/
190: PetscErrorCode PetscViewerBinaryGetMPIIO(PetscViewer viewer,PetscBool *flg)
191: {
192: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
195: *flg = vbinary->MPIIO;
196: return(0);
197: }
198: #endif
202: /*@C
203: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
205: Not Collective
207: Input Parameter:
208: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
210: Output Parameter:
211: . fc - the number of messages
213: Level: advanced
215: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
217: @*/
218: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
219: {
220: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
223: *fc = vbinary->flowcontrol;
224: return(0);
225: }
229: /*@C
230: PetscViewerBinarySetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
232: Not Collective
234: Input Parameter:
235: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
236: - fc - the number of messages, defaults to 256
238: Level: advanced
240: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
242: @*/
243: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
244: {
245: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
248: if (fc <= 1) SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
249: vbinary->flowcontrol = fc;
250: return(0);
251: }
255: /*@C
256: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
258: Not Collective
260: Input Parameter:
261: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
263: Output Parameter:
264: . fdes - file descriptor
266: Level: advanced
268: Notes:
269: For writable binary PetscViewers, the descriptor will only be valid for the
270: first processor in the communicator that shares the PetscViewer. For readable
271: files it will only be valid on nodes that have the file. If node 0 does not
272: have the file it generates an error even if another node does have the file.
274: Fortran Note:
275: This routine is not supported in Fortran.
277: Concepts: file descriptor^getting
278: Concepts: PetscViewerBinary^accessing file descriptor
280: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
281: @*/
282: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
283: {
284: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
287: *fdes = vbinary->fdes;
288: return(0);
289: }
293: /*@
294: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
296: Not Collective
298: Input Paramter:
299: . viewer - PetscViewer context, obtained from PetscViewerCreate()
301: Options Database Key:
302: . -viewer_binary_skip_info
304: Level: advanced
306: Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then
307: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
308: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().
310: The .info contains meta information about the data in the binary file, for example the block size if it was
311: set for a vector or matrix.
313: Concepts: PetscViewerBinary^accessing info file
315: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
316: PetscViewerBinaryGetSkipOptions()
317: @*/
318: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
319: {
320: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
323: vbinary->skipinfo = PETSC_TRUE;
324: return(0);
325: }
329: /*@
330: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
332: Not Collective
334: Input Parameters:
335: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
336: - skip - PETSC_TRUE means do not use
338: Options Database Key:
339: . -viewer_binary_skip_options
341: Level: advanced
343: Notes: This must be called after PetscViewerSetType()
345: Concepts: PetscViewerBinary^accessing info file
347: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
348: PetscViewerBinaryGetSkipOptions()
349: @*/
350: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
351: {
352: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
355: vbinary->skipoptions = skip;
356: return(0);
357: }
361: /*@
362: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
364: Not Collective
366: Input Parameter:
367: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
369: Output Parameter:
370: . skip - PETSC_TRUE means do not use
372: Level: advanced
374: Notes: This must be called after PetscViewerSetType()
376: Concepts: PetscViewerBinary^accessing info file
378: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
379: PetscViewerBinarySetSkipOptions()
380: @*/
381: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
382: {
383: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
386: *skip = vbinary->skipoptions;
387: return(0);
388: }
392: /*@
393: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
395: Not Collective
397: Input Parameters:
398: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
399: - skip - PETSC_TRUE means do not write header
401: Options Database Key:
402: . -viewer_binary_skip_header
404: Level: advanced
406: Notes: This must be called after PetscViewerSetType()
408: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
409: PetscViewerBinaryGetSkipHeader()
410: @*/
411: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
412: {
413: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
416: vbinary->skipheader = skip;
417: return(0);
418: }
422: /*@
423: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
425: Not Collective
427: Input Parameter:
428: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
430: Output Parameter:
431: . skip - PETSC_TRUE means do not write header
433: Level: advanced
435: Notes: This must be called after PetscViewerSetType()
437: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
438: PetscViewerBinarySetSkipHeader()
439: @*/
440: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
441: {
442: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
445: *skip = vbinary->skipheader;
446: return(0);
447: }
451: /*@C
452: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
453: info file associated with a binary file.
455: Not Collective
457: Input Parameter:
458: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
460: Output Parameter:
461: . file - file pointer
463: Level: advanced
465: Notes:
466: For writable binary PetscViewers, the descriptor will only be valid for the
467: first processor in the communicator that shares the PetscViewer.
469: Fortran Note:
470: This routine is not supported in Fortran.
472: Concepts: PetscViewerBinary^accessing info file
474: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
475: @*/
476: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
477: {
478: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
481: *file = vbinary->fdes_info;
482: return(0);
483: }
487: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
488: {
489: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
490: PetscErrorCode ierr;
491: PetscMPIInt rank;
492: int err;
495: MPI_Comm_rank(((PetscObject)v)->comm,&rank);
496: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
497: close(vbinary->fdes);
498: if (!rank && vbinary->storecompressed) {
499: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
500: FILE *fp;
501: /* compress the file */
502: PetscStrcpy(par,"gzip -f ");
503: PetscStrcat(par,vbinary->filename);
504: #if defined(PETSC_HAVE_POPEN)
505: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
506: if (fgets(buf,1024,fp)) {
507: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
508: }
509: PetscPClose(PETSC_COMM_SELF,fp);
510: #else
511: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
512: #endif
513: }
514: }
515: if (vbinary->fdes_info) {
516: err = fclose(vbinary->fdes_info);
517: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
518: }
519: PetscFree(vbinary->filename);
520: PetscFree(vbinary);
521: return(0);
522: }
524: #if defined(PETSC_HAVE_MPIIO)
527: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
528: {
529: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
530: PetscErrorCode ierr;
531: int err;
534: if (vbinary->mfdes) {
535: MPI_File_close(&vbinary->mfdes);
536: }
537: if (vbinary->fdes_info) {
538: err = fclose(vbinary->fdes_info);
539: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
540: }
541: PetscFree(vbinary->filename);
542: PetscFree(vbinary);
543: return(0);
544: }
545: #endif
549: /*@C
550: PetscViewerBinaryOpen - Opens a file for binary input/output.
552: Collective on MPI_Comm
554: Input Parameters:
555: + comm - MPI communicator
556: . name - name of file
557: - type - type of file
558: $ FILE_MODE_WRITE - create new file for binary output
559: $ FILE_MODE_READ - open existing file for binary input
560: $ FILE_MODE_APPEND - open existing file for binary output
562: Output Parameter:
563: . binv - PetscViewer for binary input/output to use with the specified file
565: Options Database Keys:
566: + -viewer_binary_skip_info
567: . -viewer_binary_skip_options
568: - -viewer_binary_skip_header
570: Level: beginner
572: Note:
573: This PetscViewer should be destroyed with PetscViewerDestroy().
575: For reading files, the filename may begin with ftp:// or http:// and/or
576: end with .gz; in this case file is brought over and uncompressed.
578: For creating files, if the file name ends with .gz it is automatically
579: compressed when closed.
581: For writing files it only opens the file on processor 0 in the communicator.
582: For readable files it opens the file on all nodes that have the file. If
583: node 0 does not have the file it generates an error even if other nodes
584: do have the file.
586: Concepts: binary files
587: Concepts: PetscViewerBinary^creating
588: Concepts: gzip
589: Concepts: accessing remote file
590: Concepts: remote file
592: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
593: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
594: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
595: @*/
596: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
597: {
601: PetscViewerCreate(comm,binv);
602: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
603: PetscViewerFileSetMode(*binv,type);
604: PetscViewerFileSetName(*binv,name);
605: return(0);
606: }
608: #if defined(PETSC_HAVE_MPIIO)
611: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool write)
612: {
613: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
614: PetscErrorCode ierr;
615: MPI_Datatype mdtype;
616: PetscMPIInt cnt = PetscMPIIntCast(count);
617: MPI_Status status;
618: MPI_Aint ul,dsize;
621: PetscDataTypeToMPIDataType(dtype,&mdtype);
622: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
623: if (write) {
624: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
625: } else {
626: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
627: }
628: MPI_Type_get_extent(mdtype,&ul,&dsize);
629: vbinary->moff += dsize*cnt;
630: return(0);
631: }
632: #endif
636: /*@C
637: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
639: Collective on MPI_Comm
641: Input Parameters:
642: + viewer - the binary viewer
643: . data - location to write the data
644: . count - number of items of data to read
645: - datatype - type of data to read
647: Level: beginner
649: Concepts: binary files
651: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
652: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
653: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
654: @*/
655: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
656: {
657: PetscErrorCode ierr;
658: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
660: #if defined(PETSC_HAVE_MPIIO)
661: if (vbinary->MPIIO) {
662: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
663: } else {
664: #endif
665: PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
666: #if defined(PETSC_HAVE_MPIIO)
667: }
668: #endif
669: return(0);
670: }
675: /*@C
676: PetscViewerBinaryWrite - writes to a binary file, only from the first process
678: Collective on MPI_Comm
680: Input Parameters:
681: + viewer - the binary viewer
682: . data - location of data
683: . count - number of items of data to read
684: . istemp - data may be overwritten
685: - datatype - type of data to read
687: Level: beginner
689: Notes: because byte-swapping may be done on the values in data it cannot be declared const
691: Concepts: binary files
693: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
694: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
695: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
696: @*/
697: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
698: {
699: PetscErrorCode ierr;
700: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
703: #if defined(PETSC_HAVE_MPIIO)
704: if (vbinary->MPIIO) {
705: PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
706: } else {
707: #endif
708: PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
709: #if defined(PETSC_HAVE_MPIIO)
710: }
711: #endif
712: return(0);
713: }
717: /*@C
718: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
720: Collective on MPI_Comm
722: Input Parameters:
723: + viewer - the binary viewer
724: - data - location of the array of strings
727: Level: intermediate
729: Concepts: binary files
731: Notes: array of strings is null terminated
733: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
734: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
735: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
736: @*/
737: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
738: {
739: PetscErrorCode ierr;
740: PetscInt i,n = 0,*sizes;
742: /* count number of strings */
743: while (data[n++]);
744: n--;
745: PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
746: sizes[0] = n;
747: for (i=0; i<n; i++) {
748: size_t tmp;
749: PetscStrlen(data[i],&tmp);
750: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
751: }
752: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
753: for (i=0; i<n; i++) {
754: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
755: }
756: PetscFree(sizes);
757: return(0);
758: }
760: /*@C
761: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
763: Collective on MPI_Comm
765: Input Parameter:
766: . viewer - the binary viewer
768: Output Parameter:
769: . data - location of the array of strings
771: Level: intermediate
773: Concepts: binary files
775: Notes: array of strings is null terminated
777: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
778: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
779: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
780: @*/
781: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
782: {
783: PetscErrorCode ierr;
784: PetscInt i,n,*sizes,N = 0;
786: /* count number of strings */
787: PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
788: PetscMalloc(n*sizeof(PetscInt),&sizes);
789: PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
790: for (i=0; i<n; i++) {
791: N += sizes[i];
792: }
793: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
794: (*data)[0] = (char*)((*data) + n + 1);
795: for (i=1; i<n; i++) {
796: (*data)[i] = (*data)[i-1] + sizes[i-1];
797: }
798: PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
799: (*data)[n] = 0;
800: PetscFree(sizes);
801: return(0);
802: }
807: PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
808: {
809: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
812: *name = vbinary->filename;
813: return(0);
814: }
819: /*@C
820: PetscViewerFileGetMode - Gets the type of file to be open
822: Not Collective
824: Input Parameter:
825: . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer
827: Output Parameter:
828: . type - type of file
829: $ FILE_MODE_WRITE - create new file for binary output
830: $ FILE_MODE_READ - open existing file for binary input
831: $ FILE_MODE_APPEND - open existing file for binary output
833: Level: advanced
835: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
837: @*/
838: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
839: {
845: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
846: return(0);
847: }
851: /*@
852: PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
853: before PetscViewerFileSetName()
855: Logically Collective on PetscViewer
857: Input Parameters:
858: . viewer - the PetscViewer; must be a binary
860: Options Database:
861: -viewer_binary_mpiio : Flag for using MPI-IO
863: Notes: turns off the default usage of the .info file since that is not scalable
865: Level: advanced
867: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
869: @*/
870: PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer)
871: {
876: PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));
877: return(0);
878: }
883: /*@C
884: PetscViewerFileSetMode - Sets the type of file to be open
886: Logically Collective on PetscViewer
888: Input Parameters:
889: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
890: - type - type of file
891: $ FILE_MODE_WRITE - create new file for binary output
892: $ FILE_MODE_READ - open existing file for binary input
893: $ FILE_MODE_APPEND - open existing file for binary output
895: Level: advanced
897: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
899: @*/
900: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
901: {
907: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
908: return(0);
909: }
914: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
915: {
916: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
919: *type = vbinary->btype;
920: return(0);
921: }
927: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
928: {
929: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
932: vbinary->btype = type;
933: return(0);
934: }
937: /*
938: Actually opens the file
939: */
943: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
944: {
945: PetscMPIInt rank;
946: PetscErrorCode ierr;
947: size_t len;
948: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
949: const char *fname;
950: char bname[PETSC_MAX_PATH_LEN],*gz;
951: PetscBool found;
952: PetscFileMode type = vbinary->btype;
955: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
956: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
957: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
958: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,PETSC_NULL);
960: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
962: /* copy name so we can edit it */
963: PetscStrallocpy(name,&vbinary->filename);
965: /* if ends in .gz strip that off and note user wants file compressed */
966: vbinary->storecompressed = PETSC_FALSE;
967: if (!rank && type == FILE_MODE_WRITE) {
968: /* remove .gz if it ends library name */
969: PetscStrstr(vbinary->filename,".gz",&gz);
970: if (gz) {
971: PetscStrlen(gz,&len);
972: if (len == 3) {
973: *gz = 0;
974: vbinary->storecompressed = PETSC_TRUE;
975: }
976: }
977: }
979: /* only first processor opens file if writeable */
980: if (!rank || type == FILE_MODE_READ) {
982: if (type == FILE_MODE_READ){
983: /* possibly get the file from remote site or compressed file */
984: PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
985: fname = bname;
986: if (!rank && !found) {
987: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
988: } else if (!found) {
989: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
990: fname = 0;
991: }
992: } else {
993: fname = vbinary->filename;
994: }
996: #if defined(PETSC_HAVE_O_BINARY)
997: if (type == FILE_MODE_WRITE) {
998: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
999: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1000: }
1001: } else if (type == FILE_MODE_READ && fname) {
1002: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
1003: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1004: }
1005: } else if (type == FILE_MODE_APPEND) {
1006: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
1007: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1008: }
1009: } else if (fname) {
1010: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1011: }
1012: #else
1013: if (type == FILE_MODE_WRITE) {
1014: if ((vbinary->fdes = creat(fname,0666)) == -1) {
1015: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1016: }
1017: } else if (type == FILE_MODE_READ && fname) {
1018: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
1019: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1020: }
1021: } else if (type == FILE_MODE_APPEND) {
1022: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
1023: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1024: }
1025: } else if (fname) {
1026: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1027: }
1028: #endif
1029: } else vbinary->fdes = -1;
1030: viewer->format = PETSC_VIEWER_NOFORMAT;
1032: /*
1033: try to open info file: all processors open this file if read only
1034: */
1035: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1036: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1038: PetscStrcpy(infoname,name);
1039: /* remove .gz if it ends library name */
1040: PetscStrstr(infoname,".gz",&gz);
1041: if (gz) {
1042: PetscStrlen(gz,&len);
1043: if (len == 3) {
1044: *gz = 0;
1045: }
1046: }
1048: PetscStrcat(infoname,".info");
1049: PetscFixFilename(infoname,iname);
1050: if (type == FILE_MODE_READ) {
1051: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1052: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1053: } else {
1054: vbinary->fdes_info = fopen(infoname,"w");
1055: if (!vbinary->fdes_info) {
1056: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1057: }
1058: }
1059: }
1061: #if defined(PETSC_USE_LOG)
1062: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1063: #endif
1064: return(0);
1065: }
1068: #if defined(PETSC_HAVE_MPIIO)
1072: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
1073: {
1074: PetscMPIInt rank;
1075: PetscErrorCode ierr;
1076: size_t len;
1077: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1078: char *gz;
1079: PetscBool found;
1080: PetscFileMode type = vbinary->btype;
1083: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
1084: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1085: PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
1087: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1088: PetscStrallocpy(name,&vbinary->filename);
1089: vbinary->storecompressed = PETSC_FALSE;
1092: /* only first processor opens file if writeable */
1093: if (type == FILE_MODE_READ) {
1094: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1095: } else if (type == FILE_MODE_WRITE) {
1096: MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1097: }
1098: viewer->format = PETSC_VIEWER_NOFORMAT;
1100: /*
1101: try to open info file: all processors open this file if read only
1103: Below is identical code to the code for Binary above, should be put in seperate routine
1104: */
1105: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1106: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1108: PetscStrcpy(infoname,name);
1109: /* remove .gz if it ends library name */
1110: PetscStrstr(infoname,".gz",&gz);
1111: if (gz) {
1112: PetscStrlen(gz,&len);
1113: if (len == 3) {
1114: *gz = 0;
1115: }
1116: }
1118: PetscStrcat(infoname,".info");
1119: PetscFixFilename(infoname,iname);
1120: if (type == FILE_MODE_READ) {
1121: PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1122: PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1123: } else {
1124: vbinary->fdes_info = fopen(infoname,"w");
1125: if (!vbinary->fdes_info) {
1126: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1127: }
1128: }
1129: }
1131: #if defined(PETSC_USE_LOG)
1132: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1133: #endif
1134: return(0);
1135: }
1141: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1142: {
1143: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1144: PetscErrorCode ierr;
1147: if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1148: viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1149: vbinary->MPIIO = PETSC_TRUE;
1150: /* vbinary->skipinfo = PETSC_TRUE; */
1151: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1152: return(0);
1153: }
1155: #endif
1160: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1161: {
1162: PetscErrorCode ierr;
1163: PetscViewer_Binary *vbinary;
1164: #if defined(PETSC_HAVE_MPIIO)
1165: PetscBool useMPIIO = PETSC_FALSE;
1166: #endif
1169: PetscNewLog(v,PetscViewer_Binary,&vbinary);
1170: v->data = (void*)vbinary;
1171: v->ops->destroy = PetscViewerDestroy_Binary;
1172: v->ops->flush = 0;
1173: v->iformat = 0;
1174: vbinary->fdes_info = 0;
1175: vbinary->fdes = 0;
1176: vbinary->skipinfo = PETSC_FALSE;
1177: vbinary->skipoptions = PETSC_TRUE;
1178: vbinary->skipheader = PETSC_FALSE;
1179: v->ops->getsingleton = PetscViewerGetSingleton_Binary;
1180: v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1181: vbinary->btype = (PetscFileMode) -1;
1182: vbinary->storecompressed = PETSC_FALSE;
1183: vbinary->filename = 0;
1184: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1186: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1187: "PetscViewerFileSetName_Binary",
1188: PetscViewerFileSetName_Binary);
1189: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1190: "PetscViewerFileSetMode_Binary",
1191: PetscViewerFileSetMode_Binary);
1192: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1193: "PetscViewerFileGetMode_Binary",
1194: PetscViewerFileGetMode_Binary);
1195: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetName_C",
1196: "PetscViewerFileGetName_Binary",
1197: PetscViewerFileGetName_Binary);
1198: #if defined(PETSC_HAVE_MPIIO)
1199: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1200: "PetscViewerBinarySetMPIIO_Binary",
1201: PetscViewerBinarySetMPIIO_Binary);
1203: PetscOptionsGetBool(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1204: if (useMPIIO) {
1205: PetscViewerBinarySetMPIIO(v);
1206: }
1207: #endif
1208: return(0);
1209: }
1213: /* ---------------------------------------------------------------------*/
1214: /*
1215: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1216: is attached to a communicator, in this case the attribute is a PetscViewer.
1217: */
1218: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1222: /*@C
1223: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1224: in a communicator.
1226: Collective on MPI_Comm
1228: Input Parameter:
1229: . comm - the MPI communicator to share the binary PetscViewer
1231: Level: intermediate
1233: Options Database Keys:
1234: + -viewer_binary_filename <name>
1235: . -viewer_binary_skip_info
1236: - -viewer_binary_skip_options
1238: Environmental variables:
1239: - PETSC_VIEWER_BINARY_FILENAME
1241: Notes:
1242: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1243: an error code. The binary PetscViewer is usually used in the form
1244: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1246: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1247: PetscViewerDestroy()
1248: @*/
1249: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1250: {
1252: PetscBool flg;
1253: PetscViewer viewer;
1254: char fname[PETSC_MAX_PATH_LEN];
1255: MPI_Comm ncomm;
1258: PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1259: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1260: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1261: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1262: }
1263: MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1264: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1265: if (!flg) { /* PetscViewer not yet created */
1266: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1267: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1268: if (!flg) {
1269: PetscStrcpy(fname,"binaryoutput");
1270: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1271: }
1272: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1273: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1274: PetscObjectRegisterDestroy((PetscObject)viewer);
1275: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1276: MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1277: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1278: }
1279: PetscCommDestroy(&ncomm);
1280: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1281: PetscFunctionReturn(viewer);
1282: }