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