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