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