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