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