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