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