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