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