xref: /petsc/src/sys/classes/viewer/impls/binary/binv.c (revision f8e4bde84cdee892096ab78baf4256ae384d8e42)
1 
2 #include <petsc-private/viewerimpl.h>    /*I   "petscviewer.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
10 
11 typedef struct  {
12   int           fdes;                 /* file descriptor, ignored if using MPI IO */
13 #if defined(PETSC_HAVE_MPIIO)
14   PetscBool     usempiio;
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   PetscBool     matlabheaderwritten;  /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
27   PetscBool     setfromoptionscalled;
28 } PetscViewer_Binary;
29 
30 #undef __FUNCT__
31 #define __FUNCT__ "PetscViewerGetSingleton_Binary"
32 PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
33 {
34   int                rank;
35   PetscErrorCode     ierr;
36   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
37 
38   PetscFunctionBegin;
39   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
40   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
41   if (!rank) {
42     ierr    = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr);
43     ierr    = PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);CHKERRQ(ierr);
44     obinary = (PetscViewer_Binary*)(*outviewer)->data;
45     ierr    = PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));CHKERRQ(ierr);
46   } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get singleton viewer for binary files or sockets");
47   PetscFunctionReturn(0);
48 }
49 
50 #undef __FUNCT__
51 #define __FUNCT__ "PetscViewerRestoreSingleton_Binary"
52 PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
53 {
54   PetscErrorCode ierr;
55   PetscErrorCode rank;
56 
57   PetscFunctionBegin;
58   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
59   if (!rank) {
60     ierr = PetscFree((*outviewer)->data);CHKERRQ(ierr);
61     ierr = PetscHeaderDestroy(outviewer);CHKERRQ(ierr);
62   }
63   PetscFunctionReturn(0);
64 }
65 
66 #if defined(PETSC_HAVE_MPIIO)
67 #undef __FUNCT__
68 #define __FUNCT__ "PetscViewerBinaryGetMPIIOOffset"
69 /*@C
70     PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
71 
72     Not Collective
73 
74     Input Parameter:
75 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
76 
77     Output Parameter:
78 .    off - the current offset
79 
80     Level: advanced
81 
82     Fortran Note:
83     This routine is not supported in Fortran.
84 
85     Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
86 
87   Concepts: file descriptor^getting
88   Concepts: PetscViewerBinary^accessing file descriptor
89 
90 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
91 @*/
92 PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
93 {
94   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
95 
96   PetscFunctionBegin;
97   *off = vbinary->moff;
98   PetscFunctionReturn(0);
99 }
100 
101 #undef __FUNCT__
102 #define __FUNCT__ "PetscViewerBinaryAddMPIIOOffset"
103 /*@C
104     PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
105 
106     Not Collective
107 
108     Input Parameters:
109 +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
110 -    off - the addition to the offset
111 
112     Level: advanced
113 
114     Fortran Note:
115     This routine is not supported in Fortran.
116 
117     Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
118 
119   Concepts: file descriptor^getting
120   Concepts: PetscViewerBinary^accessing file descriptor
121 
122 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
123 @*/
124 PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
125 {
126   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
127 
128   PetscFunctionBegin;
129   vbinary->moff += off;
130   PetscFunctionReturn(0);
131 }
132 
133 #undef __FUNCT__
134 #define __FUNCT__ "PetscViewerBinaryGetMPIIODescriptor"
135 /*@C
136     PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
137 
138     Not Collective
139 
140     Input Parameter:
141 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
142 
143     Output Parameter:
144 .   fdes - file descriptor
145 
146     Level: advanced
147 
148     Fortran Note:
149     This routine is not supported in Fortran.
150 
151   Concepts: file descriptor^getting
152   Concepts: PetscViewerBinary^accessing file descriptor
153 
154 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
155 @*/
156 PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
157 {
158   PetscErrorCode     ierr;
159   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
160 
161   PetscFunctionBegin;
162   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
163   *fdes = vbinary->mfdes;
164   PetscFunctionReturn(0);
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "PetscViewerBinaryGetUseMPIIO_Binary"
169 PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool  *flg)
170 {
171   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
172 
173   PetscFunctionBegin;
174   *flg = vbinary->usempiio;
175   PetscFunctionReturn(0);
176 }
177 #endif
178 
179 
180 #undef __FUNCT__
181 #define __FUNCT__ "PetscViewerBinaryGetUseMPIIO"
182 /*@C
183     PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
184 
185     Not Collective
186 
187     Input Parameter:
188 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
189 
190     Output Parameter:
191 -   flg - PETSC_TRUE if MPI-IO is being used
192 
193     Options Database:
194     -viewer_binary_mpiio : Flag for using MPI-IO
195 
196     Level: advanced
197 
198     Note:
199     If MPI-IO is not available, this function will always return PETSC_FALSE
200 
201     Fortran Note:
202     This routine is not supported in Fortran.
203 
204   Concepts: file descriptor^getting
205   Concepts: PetscViewerBinary^accessing file descriptor
206 
207 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
208 @*/
209 PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
210 {
211   PetscErrorCode ierr;
212 
213   PetscFunctionBegin;
214   *flg = PETSC_FALSE;
215   ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));CHKERRQ(ierr);
216   PetscFunctionReturn(0);
217 }
218 
219 #undef __FUNCT__
220 #define __FUNCT__ "PetscViewerBinaryGetFlowControl_Binary"
221 PetscErrorCode  PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
222 {
223   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
224 
225   PetscFunctionBegin;
226   *fc = vbinary->flowcontrol;
227   PetscFunctionReturn(0);
228 }
229 
230 #undef __FUNCT__
231 #define __FUNCT__ "PetscViewerBinaryGetFlowControl"
232 /*@C
233     PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
234 
235     Not Collective
236 
237     Input Parameter:
238 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
239 
240     Output Parameter:
241 .   fc - the number of messages
242 
243     Level: advanced
244 
245 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
246 
247 @*/
248 PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
249 {
250   PetscErrorCode ierr;
251 
252   PetscFunctionBegin;
253   ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr);
254   PetscFunctionReturn(0);
255 }
256 
257 #undef __FUNCT__
258 #define __FUNCT__ "PetscViewerBinarySetFlowControl_Binary"
259 PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
260 {
261   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
262 
263   PetscFunctionBegin;
264   if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
265   vbinary->flowcontrol = fc;
266   PetscFunctionReturn(0);
267 }
268 
269 #undef __FUNCT__
270 #define __FUNCT__ "PetscViewerBinarySetFlowControl"
271 /*@C
272     PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
273 
274     Not Collective
275 
276     Input Parameter:
277 +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
278 -   fc - the number of messages, defaults to 256 if this function was not called
279 
280     Level: advanced
281 
282 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
283 
284 @*/
285 PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
286 {
287   PetscErrorCode ierr;
288 
289   PetscFunctionBegin;
290   ierr = PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr);
291   PetscFunctionReturn(0);
292 }
293 
294 #undef __FUNCT__
295 #define __FUNCT__ "PetscViewerBinaryGetDescriptor"
296 /*@C
297     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
298 
299     Collective On PetscViewer
300 
301     Input Parameter:
302 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
303 
304     Output Parameter:
305 .   fdes - file descriptor
306 
307     Level: advanced
308 
309     Notes:
310       For writable binary PetscViewers, the descriptor will only be valid for the
311     first processor in the communicator that shares the PetscViewer. For readable
312     files it will only be valid on nodes that have the file. If node 0 does not
313     have the file it generates an error even if another node does have the file.
314 
315     Fortran Note:
316     This routine is not supported in Fortran.
317 
318     Developer Notes: This must be called on all processes because Dave May changed
319     the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
320 
321 
322   Concepts: file descriptor^getting
323   Concepts: PetscViewerBinary^accessing file descriptor
324 
325 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
326 @*/
327 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
328 {
329   PetscErrorCode     ierr;
330   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
331 
332   PetscFunctionBegin;
333   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
334   *fdes = vbinary->fdes;
335   PetscFunctionReturn(0);
336 }
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "PetscViewerBinarySkipInfo"
340 /*@
341     PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
342 
343     Not Collective
344 
345     Input Paramter:
346 .   viewer - PetscViewer context, obtained from PetscViewerCreate()
347 
348     Options Database Key:
349 .   -viewer_binary_skip_info
350 
351     Level: advanced
352 
353     Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
354     you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
355     viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
356 
357     The .info contains meta information about the data in the binary file, for example the block size if it was
358     set for a vector or matrix.
359 
360    Concepts: PetscViewerBinary^accessing info file
361 
362 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
363           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
364 @*/
365 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
366 {
367   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
368 
369   PetscFunctionBegin;
370   vbinary->skipinfo = PETSC_TRUE;
371   PetscFunctionReturn(0);
372 }
373 
374 #undef __FUNCT__
375 #define __FUNCT__ "PetscViewerBinarySetSkipInfo_Binary"
376 PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
377 {
378   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
379 
380   PetscFunctionBegin;
381   vbinary->skipinfo = skip;
382   PetscFunctionReturn(0);
383 }
384 
385 #undef __FUNCT__
386 #define __FUNCT__ "PetscViewerBinarySetSkipInfo"
387 /*@
388     PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
389 
390     Not Collective
391 
392     Input Paramter:
393 .   viewer - PetscViewer context, obtained from PetscViewerCreate()
394 
395     Options Database Key:
396 .   -viewer_binary_skip_info
397 
398     Level: advanced
399 
400     Concepts: PetscViewerBinary^accessing info file
401 
402 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
403           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
404 @*/
405 PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
406 {
407   PetscErrorCode ierr;
408 
409   PetscFunctionBegin;
410   ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
411   PetscFunctionReturn(0);
412 }
413 
414 #undef __FUNCT__
415 #define __FUNCT__ "PetscViewerBinaryGetSkipInfo_Binary"
416 PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
417 {
418   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
419 
420   PetscFunctionBegin;
421   *skip  = vbinary->skipinfo;
422   PetscFunctionReturn(0);
423 }
424 
425 #undef __FUNCT__
426 #define __FUNCT__ "PetscViewerBinaryGetSkipInfo"
427 /*@
428     PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
429 
430     Not Collective
431 
432     Input Parameter:
433 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
434 
435     Output Parameter:
436 .   skip - PETSC_TRUE implies the .info file was not generated
437 
438     Level: advanced
439 
440     Notes: This must be called after PetscViewerSetType()
441 
442     Concepts: PetscViewerBinary^accessing info file
443 
444 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
445           PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
446 @*/
447 PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
448 {
449   PetscErrorCode ierr;
450 
451   PetscFunctionBegin;
452   ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
453   PetscFunctionReturn(0);
454 }
455 
456 #undef __FUNCT__
457 #define __FUNCT__ "PetscViewerBinarySetSkipOptions_Binary"
458 PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
459 {
460   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
461 
462   PetscFunctionBegin;
463   vbinary->skipoptions = skip;
464   PetscFunctionReturn(0);
465 }
466 
467 #undef __FUNCT__
468 #define __FUNCT__ "PetscViewerBinarySetSkipOptions"
469 /*@
470     PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
471 
472     Not Collective
473 
474     Input Parameters:
475 +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
476 -   skip - PETSC_TRUE means do not use
477 
478     Options Database Key:
479 .   -viewer_binary_skip_options
480 
481     Level: advanced
482 
483     Notes: This must be called after PetscViewerSetType()
484 
485    Concepts: PetscViewerBinary^accessing info file
486 
487 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
488           PetscViewerBinaryGetSkipOptions()
489 @*/
490 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
491 {
492   PetscErrorCode ierr;
493 
494   PetscFunctionBegin;
495   ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
496   PetscFunctionReturn(0);
497 }
498 
499 #undef __FUNCT__
500 #define __FUNCT__ "PetscViewerBinaryGetSkipOptions_Binary"
501 PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
502 {
503   PetscViewer_Binary *vbinary;
504 
505   PetscFunctionBegin;
506   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
507   vbinary = (PetscViewer_Binary*)viewer->data;
508   *skip   = vbinary->skipoptions;
509   PetscFunctionReturn(0);
510 }
511 
512 #undef __FUNCT__
513 #define __FUNCT__ "PetscViewerBinaryGetSkipOptions"
514 /*@
515     PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
516 
517     Not Collective
518 
519     Input Parameter:
520 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
521 
522     Output Parameter:
523 .   skip - PETSC_TRUE means do not use
524 
525     Level: advanced
526 
527     Notes: This must be called after PetscViewerSetType()
528 
529    Concepts: PetscViewerBinary^accessing info file
530 
531 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
532           PetscViewerBinarySetSkipOptions()
533 @*/
534 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
535 {
536   PetscErrorCode ierr;
537 
538   PetscFunctionBegin;
539   ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
540   PetscFunctionReturn(0);
541 }
542 
543 #undef __FUNCT__
544 #define __FUNCT__ "PetscViewerBinarySetSkipHeader_Binary"
545 PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
546 {
547   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
548 
549   PetscFunctionBegin;
550   vbinary->skipheader = skip;
551   PetscFunctionReturn(0);
552 }
553 
554 #undef __FUNCT__
555 #define __FUNCT__ "PetscViewerBinarySetSkipHeader"
556 /*@
557     PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
558 
559     Not Collective
560 
561     Input Parameters:
562 +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
563 -   skip - PETSC_TRUE means do not write header
564 
565     Options Database Key:
566 .   -viewer_binary_skip_header
567 
568     Level: advanced
569 
570     Notes: This must be called after PetscViewerSetType()
571 
572            Can ONLY be called on a binary viewer
573 
574 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
575           PetscViewerBinaryGetSkipHeader()
576 @*/
577 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
578 {
579   PetscErrorCode ierr;
580 
581   PetscFunctionBegin;
582   ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
583   PetscFunctionReturn(0);
584 }
585 
586 #undef __FUNCT__
587 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader_Binary"
588 PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool  *skip)
589 {
590   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
591 
592   PetscFunctionBegin;
593   *skip = vbinary->skipheader;
594   PetscFunctionReturn(0);
595 }
596 
597 #undef __FUNCT__
598 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader"
599 /*@
600     PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
601 
602     Not Collective
603 
604     Input Parameter:
605 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
606 
607     Output Parameter:
608 .   skip - PETSC_TRUE means do not write header
609 
610     Level: advanced
611 
612     Notes: This must be called after PetscViewerSetType()
613 
614             Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
615 
616 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
617           PetscViewerBinarySetSkipHeader()
618 @*/
619 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
620 {
621   PetscErrorCode ierr;
622 
623   PetscFunctionBegin;
624   *skip = PETSC_FALSE;
625   ierr  = PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
626   PetscFunctionReturn(0);
627 }
628 
629 #undef __FUNCT__
630 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer_Binary"
631 PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
632 {
633   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
634   PetscErrorCode     ierr;
635   MPI_Comm           comm;
636 
637   PetscFunctionBegin;
638   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
639   *file = vbinary->fdes_info;
640   if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
641     vbinary->matlabheaderwritten = PETSC_TRUE;
642     ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
643     ierr = PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
644     ierr = PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr);
645     ierr = PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr);
646     ierr = PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
647   }
648   PetscFunctionReturn(0);
649 }
650 
651 #undef __FUNCT__
652 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer"
653 /*@C
654     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
655           info file associated with a binary file.
656 
657     Not Collective
658 
659     Input Parameter:
660 .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
661 
662     Output Parameter:
663 .   file - file pointer  Always returns NULL if not a binary viewer
664 
665     Level: advanced
666 
667     Notes:
668       For writable binary PetscViewers, the descriptor will only be valid for the
669     first processor in the communicator that shares the PetscViewer.
670 
671     Fortran Note:
672     This routine is not supported in Fortran.
673 
674   Concepts: PetscViewerBinary^accessing info file
675 
676 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
677 @*/
678 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
679 {
680   PetscErrorCode ierr;
681 
682   PetscFunctionBegin;
683   *file = NULL;
684   ierr  = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr);
685   PetscFunctionReturn(0);
686 }
687 
688 #undef __FUNCT__
689 #define __FUNCT__ "PetscViewerFileClose_Binary"
690 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
691 {
692   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
693   PetscErrorCode     ierr;
694   PetscMPIInt        rank;
695   int                err;
696 
697   PetscFunctionBegin;
698   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr);
699   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
700     close(vbinary->fdes);
701     if (!rank && vbinary->storecompressed) {
702       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
703       FILE *fp;
704       /* compress the file */
705       ierr = PetscStrcpy(par,"gzip -f ");CHKERRQ(ierr);
706       ierr = PetscStrcat(par,vbinary->filename);CHKERRQ(ierr);
707 #if defined(PETSC_HAVE_POPEN)
708       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr);
709       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
710       ierr = PetscPClose(PETSC_COMM_SELF,fp,NULL);CHKERRQ(ierr);
711 #else
712       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
713 #endif
714     }
715   }
716   if (vbinary->fdes_info) {
717     err = fclose(vbinary->fdes_info);
718     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
719   }
720   PetscFunctionReturn(0);
721 }
722 
723 #if defined(PETSC_HAVE_MPIIO)
724 #undef __FUNCT__
725 #define __FUNCT__ "PetscViewerFileClose_BinaryMPIIO"
726 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
727 {
728   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
729   int                err;
730   PetscErrorCode     ierr;
731 
732   PetscFunctionBegin;
733   if (vbinary->mfdes) {
734     ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr);
735   }
736   if (vbinary->fdes_info) {
737     err = fclose(vbinary->fdes_info);
738     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
739   }
740   PetscFunctionReturn(0);
741 }
742 #endif
743 
744 #undef __FUNCT__
745 #define __FUNCT__ "PetscViewerDestroy_Binary"
746 PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
747 {
748   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
749   PetscErrorCode     ierr;
750 
751   PetscFunctionBegin;
752   if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
753     MPI_Comm comm;
754     FILE     *info;
755 
756     ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
757     ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr);
758     ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
759     ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr);
760     ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
761   }
762 #if defined(PETSC_HAVE_MPIIO)
763   if (vbinary->usempiio) {
764     ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr);
765   } else {
766 #endif
767     ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr);
768 #if defined(PETSC_HAVE_MPIIO)
769   }
770 #endif
771   if (vbinary->filename) { ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); }
772   ierr = PetscFree(vbinary);CHKERRQ(ierr);
773   PetscFunctionReturn(0);
774 }
775 
776 #undef __FUNCT__
777 #define __FUNCT__ "PetscViewerBinaryOpen"
778 /*@C
779    PetscViewerBinaryOpen - Opens a file for binary input/output.
780 
781    Collective on MPI_Comm
782 
783    Input Parameters:
784 +  comm - MPI communicator
785 .  name - name of file
786 -  type - type of file
787 $    FILE_MODE_WRITE - create new file for binary output
788 $    FILE_MODE_READ - open existing file for binary input
789 $    FILE_MODE_APPEND - open existing file for binary output
790 
791    Output Parameter:
792 .  binv - PetscViewer for binary input/output to use with the specified file
793 
794     Options Database Keys:
795 +    -viewer_binary_filename <name>
796 .    -viewer_binary_skip_info
797 .    -viewer_binary_skip_options
798 .    -viewer_binary_skip_header
799 -    -viewer_binary_mpiio
800 
801    Level: beginner
802 
803    Note:
804    This PetscViewer should be destroyed with PetscViewerDestroy().
805 
806     For reading files, the filename may begin with ftp:// or http:// and/or
807     end with .gz; in this case file is brought over and uncompressed.
808 
809     For creating files, if the file name ends with .gz it is automatically
810     compressed when closed.
811 
812     For writing files it only opens the file on processor 0 in the communicator.
813     For readable files it opens the file on all nodes that have the file. If
814     node 0 does not have the file it generates an error even if other nodes
815     do have the file.
816 
817    Concepts: binary files
818    Concepts: PetscViewerBinary^creating
819    Concepts: gzip
820    Concepts: accessing remote file
821    Concepts: remote file
822 
823 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
824           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
825           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
826 @*/
827 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
828 {
829   PetscErrorCode ierr;
830 
831   PetscFunctionBegin;
832   ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr);
833   ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr);
834   ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr);
835   ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr);
836   ierr = PetscViewerSetFromOptions(*binv);CHKERRQ(ierr);
837   PetscFunctionReturn(0);
838 }
839 
840 #if defined(PETSC_HAVE_MPIIO)
841 #undef __FUNCT__
842 #define __FUNCT__ "PetscViewerBinaryWriteReadMPIIO"
843 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt *count,PetscDataType dtype,PetscBool write)
844 {
845   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
846   PetscErrorCode     ierr;
847   MPI_Datatype       mdtype;
848   PetscMPIInt        cnt;
849   MPI_Status         status;
850   MPI_Aint           ul,dsize;
851 
852   PetscFunctionBegin;
853   ierr = PetscMPIIntCast(*count,&cnt);CHKERRQ(ierr);
854   ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr);
855   ierr = MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr);
856   if (write) {
857     ierr = MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr);
858   } else {
859     ierr = MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr);
860   }
861   ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr);
862 
863   vbinary->moff += dsize*cnt;
864   PetscFunctionReturn(0);
865 }
866 #endif
867 
868 #undef __FUNCT__
869 #define __FUNCT__ "PetscViewerBinaryRead"
870 /*@C
871    PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
872 
873    Collective on MPI_Comm
874 
875    Input Parameters:
876 +  viewer - the binary viewer
877 .  data - location of the data to be written
878 .  count - number of items of data to read
879 -  dtype - type of data to read
880 
881    Output Parameters:
882 .  count - number of items of data actually read
883 
884    Level: beginner
885 
886    Concepts: binary files
887 
888 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
889           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
890           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
891 @*/
892 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt *count,PetscDataType dtype)
893 {
894   PetscErrorCode     ierr;
895   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
896 
897   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
898 #if defined(PETSC_HAVE_MPIIO)
899   if (vbinary->usempiio) {
900     ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,dtype,PETSC_FALSE);CHKERRQ(ierr);
901   } else {
902 #endif
903     ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,*count,dtype);CHKERRQ(ierr);
904 #if defined(PETSC_HAVE_MPIIO)
905   }
906 #endif
907   PetscFunctionReturn(0);
908 }
909 
910 #undef __FUNCT__
911 #define __FUNCT__ "PetscViewerBinaryWrite"
912 /*@C
913    PetscViewerBinaryWrite - writes to a binary file, only from the first process
914 
915    Collective on MPI_Comm
916 
917    Input Parameters:
918 +  viewer - the binary viewer
919 .  data - location of data
920 .  count - number of items of data to write
921 .  dtype - type of data to write
922 -  istemp - data may be overwritten
923 
924    Level: beginner
925 
926    Notes: because byte-swapping may be done on the values in data it cannot be declared const
927 
928    Concepts: binary files
929 
930 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
931           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
932           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
933 @*/
934 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
935 {
936   PetscErrorCode     ierr;
937   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
938 
939   PetscFunctionBegin;
940   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
941 #if defined(PETSC_HAVE_MPIIO)
942   if (vbinary->usempiio) {
943     ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,&count,dtype,PETSC_TRUE);CHKERRQ(ierr);
944   } else {
945 #endif
946     ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr);
947 #if defined(PETSC_HAVE_MPIIO)
948   }
949 #endif
950   PetscFunctionReturn(0);
951 }
952 
953 #undef __FUNCT__
954 #define __FUNCT__ "PetscViewerBinaryWriteStringArray"
955 /*@C
956    PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
957 
958    Collective on MPI_Comm
959 
960    Input Parameters:
961 +  viewer - the binary viewer
962 -  data - location of the array of strings
963 
964 
965    Level: intermediate
966 
967    Concepts: binary files
968 
969     Notes: array of strings is null terminated
970 
971 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
972           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
973           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
974 @*/
975 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
976 {
977   PetscErrorCode ierr;
978   PetscInt       i,n = 0,*sizes;
979 
980   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
981   /* count number of strings */
982   while (data[n++]) ;
983   n--;
984   ierr     = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr);
985   sizes[0] = n;
986   for (i=0; i<n; i++) {
987     size_t tmp;
988     ierr       = PetscStrlen(data[i],&tmp);CHKERRQ(ierr);
989     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
990   }
991   ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
992   for (i=0; i<n; i++) {
993     ierr = PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
994   }
995   ierr = PetscFree(sizes);CHKERRQ(ierr);
996   PetscFunctionReturn(0);
997 }
998 
999 #undef __FUNCT__
1000 #define __FUNCT__ "PetscViewerBinaryReadStringArray"
1001 /*@C
1002    PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1003 
1004    Collective on MPI_Comm
1005 
1006    Input Parameter:
1007 .  viewer - the binary viewer
1008 
1009    Output Parameter:
1010 .  data - location of the array of strings
1011 
1012    Level: intermediate
1013 
1014    Concepts: binary files
1015 
1016     Notes: array of strings is null terminated
1017 
1018 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
1019           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1020           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1021 @*/
1022 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1023 {
1024   PetscErrorCode ierr;
1025   PetscInt       i,n,*sizes,num = 1,N = 0;
1026 
1027   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1028   /* count number of strings */
1029   ierr = PetscViewerBinaryRead(viewer,&n,&num,PETSC_INT);CHKERRQ(ierr);
1030   ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr);
1031   ierr = PetscViewerBinaryRead(viewer,sizes,&n,PETSC_INT);CHKERRQ(ierr);
1032   for (i=0; i<n; i++) N += sizes[i];
1033   ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr);
1034   (*data)[0] = (char*)((*data) + n + 1);
1035   for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1036   ierr = PetscViewerBinaryRead(viewer,(*data)[0],&N,PETSC_CHAR);CHKERRQ(ierr);
1037 
1038   (*data)[n] = 0;
1039 
1040   ierr = PetscFree(sizes);CHKERRQ(ierr);
1041   PetscFunctionReturn(0);
1042 }
1043 
1044 #undef __FUNCT__
1045 #define __FUNCT__ "PetscViewerFileGetName_Binary"
1046 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1047 {
1048   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1049 
1050   PetscFunctionBegin;
1051   *name = vbinary->filename;
1052   PetscFunctionReturn(0);
1053 }
1054 
1055 #undef __FUNCT__
1056 #define __FUNCT__ "PetscViewerFileGetMode"
1057 /*@C
1058      PetscViewerFileGetMode - Gets the type of file to be open
1059 
1060     Not Collective
1061 
1062   Input Parameter:
1063 .  viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer
1064 
1065   Output Parameter:
1066 .  type - type of file
1067 $    FILE_MODE_WRITE - create new file for binary output
1068 $    FILE_MODE_READ - open existing file for binary input
1069 $    FILE_MODE_APPEND - open existing file for binary output
1070 
1071   Level: advanced
1072 
1073 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1074 
1075 @*/
1076 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1077 {
1078   PetscErrorCode ierr;
1079 
1080   PetscFunctionBegin;
1081   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1082   PetscValidPointer(type,2);
1083   ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr);
1084   PetscFunctionReturn(0);
1085 }
1086 
1087 #undef __FUNCT__
1088 #define __FUNCT__ "PetscViewerBinarySetUseMPIIO"
1089 /*@
1090     PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1091         before PetscViewerFileSetName()
1092 
1093     Logically Collective on PetscViewer
1094 
1095     Input Parameters:
1096 +   viewer - the PetscViewer; must be a binary
1097 -   flg - PETSC_TRUE means MPI-IO will be used
1098 
1099     Options Database:
1100     -viewer_binary_mpiio : Flag for using MPI-IO
1101 
1102     Level: advanced
1103 
1104 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1105           PetscViewerBinaryGetUseMPIIO()
1106 
1107 @*/
1108 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1109 {
1110   PetscErrorCode ierr;
1111 
1112   PetscFunctionBegin;
1113   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1114   ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr);
1115   PetscFunctionReturn(0);
1116 }
1117 
1118 #undef __FUNCT__
1119 #define __FUNCT__ "PetscViewerFileSetMode"
1120 /*@C
1121      PetscViewerFileSetMode - Sets the type of file to be open
1122 
1123     Logically Collective on PetscViewer
1124 
1125   Input Parameters:
1126 +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
1127 -  type - type of file
1128 $    FILE_MODE_WRITE - create new file for binary output
1129 $    FILE_MODE_READ - open existing file for binary input
1130 $    FILE_MODE_APPEND - open existing file for binary output
1131 
1132   Level: advanced
1133 
1134 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1135 
1136 @*/
1137 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1138 {
1139   PetscErrorCode ierr;
1140 
1141   PetscFunctionBegin;
1142   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1143   PetscValidLogicalCollectiveEnum(viewer,type,2);
1144   ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr);
1145   PetscFunctionReturn(0);
1146 }
1147 
1148 #undef __FUNCT__
1149 #define __FUNCT__ "PetscViewerFileGetMode_Binary"
1150 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1151 {
1152   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1153 
1154   PetscFunctionBegin;
1155   *type = vbinary->btype;
1156   PetscFunctionReturn(0);
1157 }
1158 
1159 #undef __FUNCT__
1160 #define __FUNCT__ "PetscViewerFileSetMode_Binary"
1161 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1162 {
1163   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1164 
1165   PetscFunctionBegin;
1166   vbinary->btype = type;
1167   PetscFunctionReturn(0);
1168 }
1169 
1170 #undef __FUNCT__
1171 #define __FUNCT__ "PetscViewerFileSetName_Binary"
1172 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1173 {
1174   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1175   PetscErrorCode     ierr;
1176 
1177   PetscFunctionBegin;
1178   if (vbinary->filename) { ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); }
1179   ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr);
1180   PetscFunctionReturn(0);
1181 }
1182 /*
1183         Actually opens the file
1184 */
1185 #undef __FUNCT__
1186 #define __FUNCT__ "PetscViewerFileSetUp_Binary"
1187 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1188 {
1189   PetscMPIInt        rank;
1190   PetscErrorCode     ierr;
1191   size_t             len;
1192   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1193   const char         *fname;
1194   char               bname[PETSC_MAX_PATH_LEN],*gz;
1195   PetscBool          found;
1196   PetscFileMode      type = vbinary->btype;
1197 
1198   PetscFunctionBegin;
1199   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1200   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1201   ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr);
1202 
1203   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1204 
1205   /* if ends in .gz strip that off and note user wants file compressed */
1206   vbinary->storecompressed = PETSC_FALSE;
1207   if (!rank && type == FILE_MODE_WRITE) {
1208     /* remove .gz if it ends library name */
1209     ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr);
1210     if (gz) {
1211       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1212       if (len == 3) {
1213         *gz = 0;
1214         vbinary->storecompressed = PETSC_TRUE;
1215       }
1216     }
1217   }
1218 
1219   /* only first processor opens file if writeable */
1220   if (!rank || type == FILE_MODE_READ) {
1221 
1222     if (type == FILE_MODE_READ) {
1223       /* possibly get the file from remote site or compressed file */
1224       ierr  = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1225       fname = bname;
1226       if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1227       else if (!found) {
1228         ierr  = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr);
1229         fname = 0;
1230       }
1231     } else fname = vbinary->filename;
1232 
1233 #if defined(PETSC_HAVE_O_BINARY)
1234     if (type == FILE_MODE_WRITE) {
1235       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1236     } else if (type == FILE_MODE_READ && fname) {
1237       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1238     } else if (type == FILE_MODE_APPEND) {
1239       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1240     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1241 #else
1242     if (type == FILE_MODE_WRITE) {
1243       if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1244     } else if (type == FILE_MODE_READ && fname) {
1245       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1246     } else if (type == FILE_MODE_APPEND) {
1247       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1248     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1249 #endif
1250   } else vbinary->fdes = -1;
1251 
1252   /*
1253       try to open info file: all processors open this file if read only
1254   */
1255   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1256     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1257 
1258     ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr);
1259     /* remove .gz if it ends library name */
1260     ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr);
1261     if (gz) {
1262       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1263       if (len == 3) *gz = 0;
1264     }
1265 
1266     ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr);
1267     ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr);
1268     if (type == FILE_MODE_READ) {
1269       ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1270       ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr);
1271     } else {
1272       vbinary->fdes_info = fopen(infoname,"w");
1273       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1274     }
1275   }
1276 #if defined(PETSC_USE_LOG)
1277   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1278 #endif
1279   PetscFunctionReturn(0);
1280 }
1281 
1282 #if defined(PETSC_HAVE_MPIIO)
1283 #undef __FUNCT__
1284 #define __FUNCT__ "PetscViewerFileSetUp_BinaryMPIIO"
1285 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1286 {
1287   PetscMPIInt        rank;
1288   PetscErrorCode     ierr;
1289   size_t             len;
1290   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1291   char               *gz;
1292   PetscBool          found;
1293   PetscFileMode      type = vbinary->btype;
1294 
1295   PetscFunctionBegin;
1296   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1297   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1298   ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr);
1299 
1300   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1301 
1302   vbinary->storecompressed = PETSC_FALSE;
1303 
1304   /* only first processor opens file if writeable */
1305   if (type == FILE_MODE_READ) {
1306     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr);
1307   } else if (type == FILE_MODE_WRITE) {
1308     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr);
1309   }
1310 
1311   /*
1312       try to open info file: all processors open this file if read only
1313 
1314       Below is identical code to the code for Binary above, should be put in seperate routine
1315   */
1316   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1317     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1318 
1319     ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr);
1320     /* remove .gz if it ends library name */
1321     ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr);
1322     if (gz) {
1323       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1324       if (len == 3) *gz = 0;
1325     }
1326 
1327     ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr);
1328     ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr);
1329     if (type == FILE_MODE_READ) {
1330       ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1331       ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr);
1332     } else {
1333       vbinary->fdes_info = fopen(infoname,"w");
1334       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1335     }
1336   }
1337 #if defined(PETSC_USE_LOG)
1338   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1339 #endif
1340   PetscFunctionReturn(0);
1341 }
1342 
1343 #undef __FUNCT__
1344 #define __FUNCT__ "PetscViewerBinarySetUseMPIIO_Binary"
1345 PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1346 {
1347   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1348   PetscFunctionBegin;
1349   vbinary->usempiio = flg;
1350   PetscFunctionReturn(0);
1351 }
1352 #endif
1353 
1354 #undef __FUNCT__
1355 #define __FUNCT__ "PetscViewerView_Binary"
1356 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1357 {
1358   PetscErrorCode     ierr;
1359   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1360 
1361   PetscFunctionBegin;
1362   if (binary->filename) {
1363     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr);
1364   }
1365   PetscFunctionReturn(0);
1366 }
1367 
1368 #undef __FUNCT__
1369 #define __FUNCT__ "PetscViewerSetUp_Binary"
1370 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1371 {
1372   PetscErrorCode     ierr;
1373   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1374 
1375   PetscFunctionBegin;
1376   if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); }
1377 
1378 #if defined(PETSC_HAVE_MPIIO)
1379   if (binary->usempiio) {
1380     ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr);
1381   } else {
1382 #endif
1383     ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr);
1384 #if defined(PETSC_HAVE_MPIIO)
1385   }
1386 #endif
1387   PetscFunctionReturn(0);
1388 }
1389 
1390 #undef __FUNCT__
1391 #define __FUNCT__ "PetscViewerSetFromOptions_Binary"
1392 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptions *PetscOptionsObject,PetscViewer v)
1393 {
1394   PetscErrorCode     ierr;
1395   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1396   char               defaultname[PETSC_MAX_PATH_LEN];
1397   PetscBool          flg;
1398 
1399   PetscFunctionBegin;
1400   ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr);
1401   ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr);
1402   ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr);
1403   if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); }
1404   ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,&flg);CHKERRQ(ierr);
1405   ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,&flg);CHKERRQ(ierr);
1406   ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,&flg);CHKERRQ(ierr);
1407 #if defined(PETSC_HAVE_MPIIO)
1408   ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,&flg);CHKERRQ(ierr);
1409 #endif
1410   ierr = PetscOptionsTail();CHKERRQ(ierr);
1411   binary->setfromoptionscalled = PETSC_TRUE;
1412   PetscFunctionReturn(0);
1413 }
1414 
1415 #undef __FUNCT__
1416 #define __FUNCT__ "PetscViewerCreate_Binary"
1417 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1418 {
1419   PetscErrorCode     ierr;
1420   PetscViewer_Binary *vbinary;
1421 
1422   PetscFunctionBegin;
1423   ierr                     = PetscNewLog(v,&vbinary);CHKERRQ(ierr);
1424   v->data                  = (void*)vbinary;
1425   v->ops->setfromoptions   = PetscViewerSetFromOptions_Binary;
1426   v->ops->destroy          = PetscViewerDestroy_Binary;
1427   v->ops->view             = PetscViewerView_Binary;
1428   v->ops->setup            = PetscViewerSetUp_Binary;
1429   v->ops->flush            = NULL;
1430   vbinary->fdes_info       = 0;
1431   vbinary->fdes            = 0;
1432   vbinary->skipinfo        = PETSC_FALSE;
1433   vbinary->skipoptions     = PETSC_TRUE;
1434   vbinary->skipheader      = PETSC_FALSE;
1435   vbinary->setfromoptionscalled = PETSC_FALSE;
1436   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1437   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1438   v->ops->read             = PetscViewerBinaryRead;
1439   vbinary->btype           = (PetscFileMode) -1;
1440   vbinary->storecompressed = PETSC_FALSE;
1441   vbinary->filename        = 0;
1442   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */
1443 
1444   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr);
1445   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr);
1446   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr);
1447   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr);
1448   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr);
1449   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr);
1450   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr);
1451   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr);
1452   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr);
1453   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr);
1454   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr);
1455   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr);
1456   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr);
1457 #if defined(PETSC_HAVE_MPIIO)
1458   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr);
1459   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr);
1460 #endif
1461   PetscFunctionReturn(0);
1462 }
1463 
1464 /* ---------------------------------------------------------------------*/
1465 /*
1466     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1467   is attached to a communicator, in this case the attribute is a PetscViewer.
1468 */
1469 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1470 
1471 #undef __FUNCT__
1472 #define __FUNCT__ "PETSC_VIEWER_BINARY_"
1473 /*@C
1474      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1475                      in a communicator.
1476 
1477      Collective on MPI_Comm
1478 
1479      Input Parameter:
1480 .    comm - the MPI communicator to share the binary PetscViewer
1481 
1482      Level: intermediate
1483 
1484    Options Database Keys:
1485 +    -viewer_binary_filename <name>
1486 .    -viewer_binary_skip_info
1487 .    -viewer_binary_skip_options
1488 .    -viewer_binary_skip_header
1489 -    -viewer_binary_mpiio
1490 
1491    Environmental variables:
1492 -   PETSC_VIEWER_BINARY_FILENAME
1493 
1494      Notes:
1495      Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1496      an error code.  The binary PetscViewer is usually used in the form
1497 $       XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1498 
1499 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1500           PetscViewerDestroy()
1501 @*/
1502 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1503 {
1504   PetscErrorCode ierr;
1505   PetscBool      flg;
1506   PetscViewer    viewer;
1507   char           fname[PETSC_MAX_PATH_LEN];
1508   MPI_Comm       ncomm;
1509 
1510   PetscFunctionBegin;
1511   ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1512   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1513     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1514     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1515   }
1516   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1517   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1518   if (!flg) { /* PetscViewer not yet created */
1519     ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1520     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1521     if (!flg) {
1522       ierr = PetscStrcpy(fname,"binaryoutput");
1523       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1524     }
1525     ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1526     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1527     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
1528     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1529     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1530     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1531   }
1532   ierr = PetscCommDestroy(&ncomm);
1533   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1534   PetscFunctionReturn(viewer);
1535 }
1536