xref: /petsc/src/sys/classes/viewer/impls/binary/binv.c (revision 898446f941de989eb59a155860a54be7cc14d054)
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    Level: beginner
882 
883    Concepts: binary files
884 
885 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
886           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
887           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
888 @*/
889 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
890 {
891   PetscErrorCode     ierr;
892   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
893 
894   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
895 #if defined(PETSC_HAVE_MPIIO)
896   if (vbinary->usempiio) {
897     ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,dtype,PETSC_FALSE);CHKERRQ(ierr);
898   } else {
899 #endif
900     ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);CHKERRQ(ierr);
901 #if defined(PETSC_HAVE_MPIIO)
902   }
903 #endif
904   PetscFunctionReturn(0);
905 }
906 
907 #undef __FUNCT__
908 #define __FUNCT__ "PetscViewerBinaryWrite"
909 /*@C
910    PetscViewerBinaryWrite - writes to a binary file, only from the first process
911 
912    Collective on MPI_Comm
913 
914    Input Parameters:
915 +  viewer - the binary viewer
916 .  data - location of data
917 .  count - number of items of data to write
918 .  dtype - type of data to write
919 -  istemp - data may be overwritten
920 
921    Level: beginner
922 
923    Notes: because byte-swapping may be done on the values in data it cannot be declared const
924 
925    Concepts: binary files
926 
927 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
928           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
929           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
930 @*/
931 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
932 {
933   PetscErrorCode     ierr;
934   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
935 
936   PetscFunctionBegin;
937   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
938 #if defined(PETSC_HAVE_MPIIO)
939   if (vbinary->usempiio) {
940     ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,dtype,PETSC_TRUE);CHKERRQ(ierr);
941   } else {
942 #endif
943     ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr);
944 #if defined(PETSC_HAVE_MPIIO)
945   }
946 #endif
947   PetscFunctionReturn(0);
948 }
949 
950 #undef __FUNCT__
951 #define __FUNCT__ "PetscViewerBinaryWriteStringArray"
952 /*@C
953    PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
954 
955    Collective on MPI_Comm
956 
957    Input Parameters:
958 +  viewer - the binary viewer
959 -  data - location of the array of strings
960 
961 
962    Level: intermediate
963 
964    Concepts: binary files
965 
966     Notes: array of strings is null terminated
967 
968 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
969           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
970           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
971 @*/
972 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
973 {
974   PetscErrorCode ierr;
975   PetscInt       i,n = 0,*sizes;
976 
977   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
978   /* count number of strings */
979   while (data[n++]) ;
980   n--;
981   ierr     = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr);
982   sizes[0] = n;
983   for (i=0; i<n; i++) {
984     size_t tmp;
985     ierr       = PetscStrlen(data[i],&tmp);CHKERRQ(ierr);
986     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
987   }
988   ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
989   for (i=0; i<n; i++) {
990     ierr = PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
991   }
992   ierr = PetscFree(sizes);CHKERRQ(ierr);
993   PetscFunctionReturn(0);
994 }
995 
996 #undef __FUNCT__
997 #define __FUNCT__ "PetscViewerBinaryReadStringArray"
998 /*@C
999    PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1000 
1001    Collective on MPI_Comm
1002 
1003    Input Parameter:
1004 .  viewer - the binary viewer
1005 
1006    Output Parameter:
1007 .  data - location of the array of strings
1008 
1009    Level: intermediate
1010 
1011    Concepts: binary files
1012 
1013     Notes: array of strings is null terminated
1014 
1015 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
1016           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1017           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1018 @*/
1019 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1020 {
1021   PetscErrorCode ierr;
1022   PetscInt       i,n,*sizes,N = 0;
1023 
1024   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1025   /* count number of strings */
1026   ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr);
1027   ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr);
1028   ierr = PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);CHKERRQ(ierr);
1029   for (i=0; i<n; i++) N += sizes[i];
1030   ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr);
1031   (*data)[0] = (char*)((*data) + n + 1);
1032   for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1033   ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);CHKERRQ(ierr);
1034 
1035   (*data)[n] = 0;
1036 
1037   ierr = PetscFree(sizes);CHKERRQ(ierr);
1038   PetscFunctionReturn(0);
1039 }
1040 
1041 #undef __FUNCT__
1042 #define __FUNCT__ "PetscViewerFileGetName_Binary"
1043 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1044 {
1045   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1046 
1047   PetscFunctionBegin;
1048   *name = vbinary->filename;
1049   PetscFunctionReturn(0);
1050 }
1051 
1052 #undef __FUNCT__
1053 #define __FUNCT__ "PetscViewerFileGetMode"
1054 /*@C
1055      PetscViewerFileGetMode - Gets the type of file to be open
1056 
1057     Not Collective
1058 
1059   Input Parameter:
1060 .  viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer
1061 
1062   Output Parameter:
1063 .  type - type of file
1064 $    FILE_MODE_WRITE - create new file for binary output
1065 $    FILE_MODE_READ - open existing file for binary input
1066 $    FILE_MODE_APPEND - open existing file for binary output
1067 
1068   Level: advanced
1069 
1070 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1071 
1072 @*/
1073 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1074 {
1075   PetscErrorCode ierr;
1076 
1077   PetscFunctionBegin;
1078   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1079   PetscValidPointer(type,2);
1080   ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr);
1081   PetscFunctionReturn(0);
1082 }
1083 
1084 #undef __FUNCT__
1085 #define __FUNCT__ "PetscViewerBinarySetUseMPIIO"
1086 /*@
1087     PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1088         before PetscViewerFileSetName()
1089 
1090     Logically Collective on PetscViewer
1091 
1092     Input Parameters:
1093 +   viewer - the PetscViewer; must be a binary
1094 -   flg - PETSC_TRUE means MPI-IO will be used
1095 
1096     Options Database:
1097     -viewer_binary_mpiio : Flag for using MPI-IO
1098 
1099     Level: advanced
1100 
1101 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1102           PetscViewerBinaryGetUseMPIIO()
1103 
1104 @*/
1105 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1106 {
1107   PetscErrorCode ierr;
1108 
1109   PetscFunctionBegin;
1110   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1111   ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr);
1112   PetscFunctionReturn(0);
1113 }
1114 
1115 #undef __FUNCT__
1116 #define __FUNCT__ "PetscViewerFileSetMode"
1117 /*@C
1118      PetscViewerFileSetMode - Sets the type of file to be open
1119 
1120     Logically Collective on PetscViewer
1121 
1122   Input Parameters:
1123 +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
1124 -  type - type of file
1125 $    FILE_MODE_WRITE - create new file for binary output
1126 $    FILE_MODE_READ - open existing file for binary input
1127 $    FILE_MODE_APPEND - open existing file for binary output
1128 
1129   Level: advanced
1130 
1131 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1132 
1133 @*/
1134 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1135 {
1136   PetscErrorCode ierr;
1137 
1138   PetscFunctionBegin;
1139   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1140   PetscValidLogicalCollectiveEnum(viewer,type,2);
1141   ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr);
1142   PetscFunctionReturn(0);
1143 }
1144 
1145 #undef __FUNCT__
1146 #define __FUNCT__ "PetscViewerFileGetMode_Binary"
1147 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1148 {
1149   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1150 
1151   PetscFunctionBegin;
1152   *type = vbinary->btype;
1153   PetscFunctionReturn(0);
1154 }
1155 
1156 #undef __FUNCT__
1157 #define __FUNCT__ "PetscViewerFileSetMode_Binary"
1158 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1159 {
1160   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1161 
1162   PetscFunctionBegin;
1163   vbinary->btype = type;
1164   PetscFunctionReturn(0);
1165 }
1166 
1167 #undef __FUNCT__
1168 #define __FUNCT__ "PetscViewerFileSetName_Binary"
1169 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1170 {
1171   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1172   PetscErrorCode     ierr;
1173 
1174   PetscFunctionBegin;
1175   if (vbinary->filename) { ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); }
1176   ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr);
1177   PetscFunctionReturn(0);
1178 }
1179 /*
1180         Actually opens the file
1181 */
1182 #undef __FUNCT__
1183 #define __FUNCT__ "PetscViewerFileSetUp_Binary"
1184 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1185 {
1186   PetscMPIInt        rank;
1187   PetscErrorCode     ierr;
1188   size_t             len;
1189   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1190   const char         *fname;
1191   char               bname[PETSC_MAX_PATH_LEN],*gz;
1192   PetscBool          found;
1193   PetscFileMode      type = vbinary->btype;
1194 
1195   PetscFunctionBegin;
1196   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1197   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1198   ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr);
1199 
1200   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1201 
1202   /* if ends in .gz strip that off and note user wants file compressed */
1203   vbinary->storecompressed = PETSC_FALSE;
1204   if (!rank && type == FILE_MODE_WRITE) {
1205     /* remove .gz if it ends library name */
1206     ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr);
1207     if (gz) {
1208       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1209       if (len == 3) {
1210         *gz = 0;
1211         vbinary->storecompressed = PETSC_TRUE;
1212       }
1213     }
1214   }
1215 
1216   /* only first processor opens file if writeable */
1217   if (!rank || type == FILE_MODE_READ) {
1218 
1219     if (type == FILE_MODE_READ) {
1220       /* possibly get the file from remote site or compressed file */
1221       ierr  = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1222       fname = bname;
1223       if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1224       else if (!found) {
1225         ierr  = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr);
1226         fname = 0;
1227       }
1228     } else fname = vbinary->filename;
1229 
1230 #if defined(PETSC_HAVE_O_BINARY)
1231     if (type == FILE_MODE_WRITE) {
1232       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);
1233     } else if (type == FILE_MODE_READ && fname) {
1234       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);
1235     } else if (type == FILE_MODE_APPEND) {
1236       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);
1237     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1238 #else
1239     if (type == FILE_MODE_WRITE) {
1240       if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1241     } else if (type == FILE_MODE_READ && fname) {
1242       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1243     } else if (type == FILE_MODE_APPEND) {
1244       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);
1245     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1246 #endif
1247   } else vbinary->fdes = -1;
1248 
1249   /*
1250       try to open info file: all processors open this file if read only
1251   */
1252   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1253     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1254 
1255     ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr);
1256     /* remove .gz if it ends library name */
1257     ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr);
1258     if (gz) {
1259       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1260       if (len == 3) *gz = 0;
1261     }
1262 
1263     ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr);
1264     ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr);
1265     if (type == FILE_MODE_READ) {
1266       ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1267       ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr);
1268     } else {
1269       vbinary->fdes_info = fopen(infoname,"w");
1270       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1271     }
1272   }
1273 #if defined(PETSC_USE_LOG)
1274   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1275 #endif
1276   PetscFunctionReturn(0);
1277 }
1278 
1279 #if defined(PETSC_HAVE_MPIIO)
1280 #undef __FUNCT__
1281 #define __FUNCT__ "PetscViewerFileSetUp_BinaryMPIIO"
1282 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1283 {
1284   PetscMPIInt        rank;
1285   PetscErrorCode     ierr;
1286   size_t             len;
1287   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1288   char               *gz;
1289   PetscBool          found;
1290   PetscFileMode      type = vbinary->btype;
1291 
1292   PetscFunctionBegin;
1293   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1294   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1295   ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr);
1296 
1297   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1298 
1299   vbinary->storecompressed = PETSC_FALSE;
1300 
1301   /* only first processor opens file if writeable */
1302   if (type == FILE_MODE_READ) {
1303     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr);
1304   } else if (type == FILE_MODE_WRITE) {
1305     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr);
1306   }
1307 
1308   /*
1309       try to open info file: all processors open this file if read only
1310 
1311       Below is identical code to the code for Binary above, should be put in seperate routine
1312   */
1313   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1314     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1315 
1316     ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr);
1317     /* remove .gz if it ends library name */
1318     ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr);
1319     if (gz) {
1320       ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
1321       if (len == 3) *gz = 0;
1322     }
1323 
1324     ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr);
1325     ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr);
1326     if (type == FILE_MODE_READ) {
1327       ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1328       ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr);
1329     } else {
1330       vbinary->fdes_info = fopen(infoname,"w");
1331       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1332     }
1333   }
1334 #if defined(PETSC_USE_LOG)
1335   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1336 #endif
1337   PetscFunctionReturn(0);
1338 }
1339 
1340 #undef __FUNCT__
1341 #define __FUNCT__ "PetscViewerBinarySetUseMPIIO_Binary"
1342 PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1343 {
1344   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1345   PetscFunctionBegin;
1346   vbinary->usempiio = flg;
1347   PetscFunctionReturn(0);
1348 }
1349 #endif
1350 
1351 #undef __FUNCT__
1352 #define __FUNCT__ "PetscViewerView_Binary"
1353 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1354 {
1355   PetscErrorCode     ierr;
1356   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1357 
1358   PetscFunctionBegin;
1359   if (binary->filename) {
1360     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr);
1361   }
1362   PetscFunctionReturn(0);
1363 }
1364 
1365 #undef __FUNCT__
1366 #define __FUNCT__ "PetscViewerSetUp_Binary"
1367 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1368 {
1369   PetscErrorCode     ierr;
1370   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1371 
1372   PetscFunctionBegin;
1373   if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); }
1374 
1375 #if defined(PETSC_HAVE_MPIIO)
1376   if (binary->usempiio) {
1377     ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr);
1378   } else {
1379 #endif
1380     ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr);
1381 #if defined(PETSC_HAVE_MPIIO)
1382   }
1383 #endif
1384   PetscFunctionReturn(0);
1385 }
1386 
1387 #undef __FUNCT__
1388 #define __FUNCT__ "PetscViewerSetFromOptions_Binary"
1389 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptions *PetscOptionsObject,PetscViewer v)
1390 {
1391   PetscErrorCode     ierr;
1392   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1393   char               defaultname[PETSC_MAX_PATH_LEN];
1394   PetscBool          flg;
1395 
1396   PetscFunctionBegin;
1397   ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr);
1398   ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr);
1399   ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr);
1400   if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); }
1401   ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,&flg);CHKERRQ(ierr);
1402   ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,&flg);CHKERRQ(ierr);
1403   ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,&flg);CHKERRQ(ierr);
1404 #if defined(PETSC_HAVE_MPIIO)
1405   ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,&flg);CHKERRQ(ierr);
1406 #endif
1407   ierr = PetscOptionsTail();CHKERRQ(ierr);
1408   binary->setfromoptionscalled = PETSC_TRUE;
1409   PetscFunctionReturn(0);
1410 }
1411 
1412 #undef __FUNCT__
1413 #define __FUNCT__ "PetscViewerCreate_Binary"
1414 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1415 {
1416   PetscErrorCode     ierr;
1417   PetscViewer_Binary *vbinary;
1418 
1419   PetscFunctionBegin;
1420   ierr                     = PetscNewLog(v,&vbinary);CHKERRQ(ierr);
1421   v->data                  = (void*)vbinary;
1422   v->ops->setfromoptions   = PetscViewerSetFromOptions_Binary;
1423   v->ops->destroy          = PetscViewerDestroy_Binary;
1424   v->ops->view             = PetscViewerView_Binary;
1425   v->ops->setup            = PetscViewerSetUp_Binary;
1426   v->ops->flush            = NULL;
1427   vbinary->fdes_info       = 0;
1428   vbinary->fdes            = 0;
1429   vbinary->skipinfo        = PETSC_FALSE;
1430   vbinary->skipoptions     = PETSC_TRUE;
1431   vbinary->skipheader      = PETSC_FALSE;
1432   vbinary->setfromoptionscalled = PETSC_FALSE;
1433   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1434   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1435   v->ops->read             = PetscViewerBinaryRead;
1436   vbinary->btype           = (PetscFileMode) -1;
1437   vbinary->storecompressed = PETSC_FALSE;
1438   vbinary->filename        = 0;
1439   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */
1440 
1441   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr);
1442   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr);
1443   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr);
1444   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr);
1445   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr);
1446   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr);
1447   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr);
1448   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr);
1449   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr);
1450   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr);
1451   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr);
1452   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr);
1453   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr);
1454 #if defined(PETSC_HAVE_MPIIO)
1455   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr);
1456   ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr);
1457 #endif
1458   PetscFunctionReturn(0);
1459 }
1460 
1461 /* ---------------------------------------------------------------------*/
1462 /*
1463     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1464   is attached to a communicator, in this case the attribute is a PetscViewer.
1465 */
1466 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1467 
1468 #undef __FUNCT__
1469 #define __FUNCT__ "PETSC_VIEWER_BINARY_"
1470 /*@C
1471      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1472                      in a communicator.
1473 
1474      Collective on MPI_Comm
1475 
1476      Input Parameter:
1477 .    comm - the MPI communicator to share the binary PetscViewer
1478 
1479      Level: intermediate
1480 
1481    Options Database Keys:
1482 +    -viewer_binary_filename <name>
1483 .    -viewer_binary_skip_info
1484 .    -viewer_binary_skip_options
1485 .    -viewer_binary_skip_header
1486 -    -viewer_binary_mpiio
1487 
1488    Environmental variables:
1489 -   PETSC_VIEWER_BINARY_FILENAME
1490 
1491      Notes:
1492      Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1493      an error code.  The binary PetscViewer is usually used in the form
1494 $       XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1495 
1496 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1497           PetscViewerDestroy()
1498 @*/
1499 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1500 {
1501   PetscErrorCode ierr;
1502   PetscBool      flg;
1503   PetscViewer    viewer;
1504   char           fname[PETSC_MAX_PATH_LEN];
1505   MPI_Comm       ncomm;
1506 
1507   PetscFunctionBegin;
1508   ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1509   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1510     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1511     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1512   }
1513   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1514   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1515   if (!flg) { /* PetscViewer not yet created */
1516     ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1517     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1518     if (!flg) {
1519       ierr = PetscStrcpy(fname,"binaryoutput");
1520       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1521     }
1522     ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1523     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1524     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
1525     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1526     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1527     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1528   }
1529   ierr = PetscCommDestroy(&ncomm);
1530   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
1531   PetscFunctionReturn(viewer);
1532 }
1533