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