Actual source code: binv.c

  1: #define PETSC_DLL
 2:  #include src/sys/src/viewer/viewerimpl.h
 3:  #include petscsys.h
  4: #include <fcntl.h>
  5: #if defined(PETSC_HAVE_UNISTD_H)
  6: #include <unistd.h>
  7: #endif
  8: #if defined (PETSC_HAVE_IO_H)
  9: #include <io.h>
 10: #endif

 12: typedef struct  {
 13:   int                 fdes;            /* file descriptor */
 14:   PetscViewerFileType btype;           /* read or write? */
 15:   FILE                *fdes_info;      /* optional file containing info on binary file*/
 16:   PetscTruth          storecompressed; /* gzip the write binary file when closing it*/
 17:   char                *filename;
 18:   PetscTruth          skipinfo;        /* Don't create info file for writing; don't use for reading */
 19:   PetscTruth          skipoptions;     /* don't use PETSc options database when loading */
 20: } PetscViewer_Binary;

 24: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
 25: {
 26:   int                rank;
 27:   PetscErrorCode     ierr;
 28:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;

 31:   MPI_Comm_rank(viewer->comm,&rank);
 32:   if (!rank) {
 33:     PetscViewerCreate(PETSC_COMM_SELF,outviewer);
 34:     PetscViewerSetType(*outviewer,PETSC_VIEWER_BINARY);
 35:     obinary = (PetscViewer_Binary*)(*outviewer)->data;
 36:     PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
 37:   } else {
 38:     *outviewer = 0;
 39:   }
 40:   return(0);
 41: }

 45: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
 46: {
 48:   PetscErrorCode rank;

 51:   MPI_Comm_rank(viewer->comm,&rank);
 52:   if (!rank) {
 53:     PetscFree((*outviewer)->data);
 54:     PetscHeaderDestroy(*outviewer);
 55:   }
 56:   return(0);
 57: }

 61: /*@C
 62:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

 64:     Not Collective

 66: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
 67: -   fdes - file descriptor

 69:     Level: advanced

 71:     Notes:
 72:       For writable binary PetscViewers, the descriptor will only be valid for the 
 73:     first processor in the communicator that shares the PetscViewer. For readable 
 74:     files it will only be valid on nodes that have the file. If node 0 does not
 75:     have the file it generates an error even if another node does have the file.
 76:  
 77:     Fortran Note:
 78:     This routine is not supported in Fortran.

 80:   Concepts: file descriptor^getting
 81:   Concepts: PetscViewerBinary^accessing file descriptor

 83: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
 84: @*/
 85: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
 86: {
 87:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

 90:   *fdes = vbinary->fdes;
 91:   return(0);
 92: }

 96: /*@
 97:     PetscViewerBinarySkipInfo - Binary file will not have .info file created with it

 99:     Not Collective

101:     Input Paramter:
102: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

104:     Options Database Key:
105: .   -viewer_binary_skip_info

107:     Level: advanced

109:     Notes: This must be called after PetscViewerSetType() but before PetscViewerBinarySetFilename()

111:    Concepts: PetscViewerBinary^accessing info file

113: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
114:           PetscViewerBinaryGetSkipOptions()
115: @*/
116: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinarySkipInfo(PetscViewer viewer)
117: {
118:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

121:   vbinary->skipinfo = PETSC_TRUE;
122:   return(0);
123: }

127: /*@
128:     PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects

130:     Not Collective

132:     Input Paramter:
133: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
134: -   skip - PETSC_TRUE means do not use

136:     Options Database Key:
137: .   -viewer_binary_skip_options

139:     Level: advanced

141:     Notes: This must be called after PetscViewerSetType()

143:    Concepts: PetscViewerBinary^accessing info file

145: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
146:           PetscViewerBinaryGetSkipOptions()
147: @*/
148: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
149: {
150:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

153:   vbinary->skipoptions = skip;
154:   return(0);
155: }

159: /*@
160:     PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects

162:     Not Collective

164:     Input Paramter:
165: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

167:     Output Parameter:
168: .   skip - PETSC_TRUE means do not use

170:     Level: advanced

172:     Notes: This must be called after PetscViewerSetType()

174:    Concepts: PetscViewerBinary^accessing info file

176: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
177:           PetscViewerBinarySetSkipOptions()
178: @*/
179: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
180: {
181:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

184:   *skip = vbinary->skipoptions;
185:   return(0);
186: }

190: /*@C
191:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
192:           info file associated with a binary file.

194:     Not Collective

196: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
197: -   file - file pointer

199:     Level: advanced

201:     Notes:
202:       For writable binary PetscViewers, the descriptor will only be valid for the 
203:     first processor in the communicator that shares the PetscViewer.
204:  
205:     Fortran Note:
206:     This routine is not supported in Fortran.

208:   Concepts: PetscViewerBinary^accessing info file

210: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
211: @*/
212: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
213: {
214:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

217:   *file = vbinary->fdes_info;
218:   return(0);
219: }

223: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
224: {
225:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
226:   PetscErrorCode     ierr;
227:   int                rank;

230:   MPI_Comm_rank(v->comm,&rank);
231:   if ((!rank || vbinary->btype == PETSC_FILE_RDONLY ) && vbinary->fdes) {
232:     close(vbinary->fdes);
233:     if (!rank && vbinary->storecompressed) {
234:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
235:       FILE *fp;
236:       /* compress the file */
237:       PetscStrcpy(par,"gzip ");
238:       PetscStrcat(par,vbinary->filename);
239: #if defined(PETSC_HAVE_POPEN)
240:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
241:       if (fgets(buf,1024,fp)) {
242:         SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
243:       }
244:       PetscPClose(PETSC_COMM_SELF,fp);
245: #else
246:       SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
247: #endif
248:     }
249:   }
250:   if (vbinary->fdes_info) fclose(vbinary->fdes_info);
251:   PetscStrfree(vbinary->filename);
252:   PetscFree(vbinary);
253:   return(0);
254: }

258: /*@C
259:    PetscViewerBinaryOpen - Opens a file for binary input/output.

261:    Collective on MPI_Comm

263:    Input Parameters:
264: +  comm - MPI communicator
265: .  name - name of file 
266: -  type - type of file
267: $    PETSC_FILE_CREATE - create new file for binary output
268: $    PETSC_FILE_RDONLY - open existing file for binary input
269: $    PETSC_FILE_WRONLY - open existing file for binary output

271:    Output Parameter:
272: .  binv - PetscViewer for binary input/output to use with the specified file

274:    Level: beginner

276:    Note:
277:    This PetscViewer should be destroyed with PetscViewerDestroy().

279:     For reading files, the filename may begin with ftp:// or http:// and/or
280:     end with .gz; in this case file is brought over and uncompressed.

282:     For creating files, if the file name ends with .gz it is automatically 
283:     compressed when closed.

285:     For writing files it only opens the file on processor 0 in the communicator.
286:     For readable files it opens the file on all nodes that have the file. If 
287:     node 0 does not have the file it generates an error even if other nodes
288:     do have the file.

290:    Concepts: binary files
291:    Concepts: PetscViewerBinary^creating
292:    Concepts: gzip
293:    Concepts: accessing remote file
294:    Concepts: remote file

296: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
297:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
298:           PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
299: @*/
300: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscViewerFileType type,PetscViewer *binv)
301: {
303: 
305:   PetscViewerCreate(comm,binv);
306:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
307:   PetscViewerSetFileType(*binv,type);
308:   PetscViewerSetFilename(*binv,name);
309:   return(0);
310: }

314: /*@C
315:    PetscViewerBinaryRead - Reads from a binary file, all processors get the same result

317:    Collective on MPI_Comm

319:    Input Parameters:
320: +  viewer - the binary viewer
321: .  data - location to write the data
322: .  count - number of items of data to read
323: -  datatype - type of data to read

325:    Level: beginner

327:    Concepts: binary files

329: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
330:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
331:           PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
332: @*/
333: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
334: {
335:   PetscErrorCode     ierr;
336:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

338:   PetscSynchronizedBinaryRead(viewer->comm,vbinary->fdes,data,count,dtype);
339:   return(0);
340: }

344: /*@C
345:    PetscViewerBinaryWrite - writes to a binary file, only from the first process

347:    Collective on MPI_Comm

349:    Input Parameters:
350: +  viewer - the binary viewer
351: .  data - location of data
352: .  count - number of items of data to read
353: .  istemp - data may be overwritten
354: -  datatype - type of data to read

356:    Level: beginner

358:    Concepts: binary files

360: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
361:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
362:           PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
363: @*/
364: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
365: {
366:   PetscErrorCode     ierr;
367:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

369:   PetscSynchronizedBinaryWrite(viewer->comm,vbinary->fdes,data,count,dtype,istemp);
370:   return(0);
371: }

375: /*@C
376:    PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings

378:    Collective on MPI_Comm

380:    Input Parameters:
381: +  viewer - the binary viewer
382: -  data - location of the array of strings


385:    Level: intermediate

387:    Concepts: binary files

389:     Notes: array of strings is null terminated

391: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
392:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
393:           PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
394: @*/
395: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
396: {
397:   PetscErrorCode     ierr;
398:   PetscInt           i,n = 0,*sizes;

400:   /* count number of strings */
401:   while (data[n++]);
402:   n--;
403:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
404:   sizes[0] = n;
405:   for (i=0; i<n; i++) {
406:     size_t tmp;
407:     PetscStrlen(data[i],&tmp);
408:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
409:   }
410:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
411:   for (i=0; i<n; i++) {
412:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
413:   }
414:   PetscFree(sizes);
415:   return(0);
416: }

418: /*@C
419:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

421:    Collective on MPI_Comm

423:    Input Parameter:
424: .  viewer - the binary viewer

426:    Output Parameter:
427: .  data - location of the array of strings

429:    Level: intermediate

431:    Concepts: binary files

433:     Notes: array of strings is null terminated

435: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
436:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
437:           PetscViewerBinaryGetInfoPointer(), PetscViewerFileType, PetscViewer, PetscBinaryViewerRead()
438: @*/
439: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
440: {
441:   PetscErrorCode     ierr;
442:   PetscInt           i,n,*sizes,N = 0;

444:   /* count number of strings */
445:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
446:   PetscMalloc(n*sizeof(PetscInt),&sizes);
447:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
448:   for (i=0; i<n; i++) {
449:     N += sizes[i];
450:   }
451:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
452:   (*data)[0] = (char*)((*data) + n + 1);
453:   for (i=1; i<n; i++) {
454:     (*data)[i] = (*data)[i-1] + sizes[i-1];
455:   }
456:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
457:   (*data)[n] = 0;
458:   PetscFree(sizes);
459:   return(0);
460: }

464: /*@C
465:      PetscViewerSetFileType - Sets the type of file to be open

467:     Collective on PetscViewer

469:   Input Parameters:
470: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
471: -  type - type of file
472: $    PETSC_FILE_CREATE - create new file for binary output
473: $    PETSC_FILE_RDONLY - open existing file for binary input
474: $    PETSC_FILE_WRONLY - open existing file for binary output

476:   Level: advanced

478: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

480: @*/
481: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFileType(PetscViewer viewer,PetscViewerFileType type)
482: {
483:   PetscErrorCode ierr,(*f)(PetscViewer,PetscViewerFileType);

487:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFileType_C",(void (**)(void))&f);
488:   if (f) {
489:     (*f)(viewer,type);
490:   }
491:   return(0);
492: }

497: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFileType_Binary(PetscViewer viewer,PetscViewerFileType type)
498: {
499:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

502:   vbinary->btype = type;
503:   return(0);
504: }

509: /*@
510:     PetscViewerBinaryLoadInfo - Loads options from the name.info file
511:        if it exists.

513:    Collective on PetscViewer

515:   Input Parameter:
516: .    viewer - the binary viewer whose options you wish to load

518:    Level: developer

520: @*/
521: PetscErrorCode PETSC_DLLEXPORT PetscViewerBinaryLoadInfo(PetscViewer viewer)
522: {
523:   FILE               *file;
524:   char               string[256],*first,*second,*final;
525:   size_t             len;
526:   PetscErrorCode     ierr;
527:   PetscToken         *token;
528:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

531:   if (vbinary->skipinfo) return(0);

533:   PetscViewerBinaryGetInfoPointer(viewer,&file);
534:   if (!file) return(0);

536:   /* read rows of the file adding them to options database */
537:   while (fgets(string,256,file)) {
538:     /* Comments are indicated by #, ! or % in the first column */
539:     if (string[0] == '#') continue;
540:     if (string[0] == '!') continue;
541:     if (string[0] == '%') continue;
542:     PetscTokenCreate(string,' ',&token);
543:     PetscTokenFind(token,&first);
544:     PetscTokenFind(token,&second);
545:     if (first && first[0] == '-') {
546:       PetscTruth wrongtype;
547:       /*
548:          Check for -mat_complex or -mat_double
549:       */
550: #if defined(PETSC_USE_COMPLEX)
551:       PetscStrncmp(first,"-mat_double",11,&wrongtype);
552:       if (wrongtype) {
553:         SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading double number matrix with complex number code");
554:       }
555: #else
556:       PetscStrncmp(first,"-mat_complex",12,&wrongtype);
557:       if (wrongtype) {
558:         SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading complex number matrix with double number code");
559:       }
560: #endif

562:       if (second) {final = second;} else {final = first;}
563:       PetscStrlen(final,&len);
564:       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
565:         len--; final[len] = 0;
566:       }
567:       PetscOptionsSetValue(first,second);
568:     }
569:     PetscTokenDestroy(token);
570:   }
571:   return(0);
572: }

574: /*
575:         Actually opens the file 
576: */
580: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename_Binary(PetscViewer viewer,const char name[])
581: {
582:   int                 rank;
583:   PetscErrorCode      ierr;
584:   size_t              len;
585:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
586:   const char          *fname;
587:   char                bname[PETSC_MAX_PATH_LEN],*gz;
588:   PetscTruth          found;
589:   PetscViewerFileType type = vbinary->btype;

592:   if (type == (PetscViewerFileType) -1) {
593:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetType() before PetscViewerSetFilename()");
594:   }
595:   PetscOptionsGetTruth(viewer->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
596:   PetscOptionsGetTruth(viewer->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

598:   MPI_Comm_rank(viewer->comm,&rank);

600:   /* copy name so we can edit it */
601:   PetscStrallocpy(name,&vbinary->filename);

603:   /* if ends in .gz strip that off and note user wants file compressed */
604:   vbinary->storecompressed = PETSC_FALSE;
605:   if (!rank && type == PETSC_FILE_CREATE) {
606:     /* remove .gz if it ends library name */
607:     PetscStrstr(vbinary->filename,".gz",&gz);
608:     if (gz) {
609:       PetscStrlen(gz,&len);
610:       if (len == 3) {
611:         *gz = 0;
612:         vbinary->storecompressed = PETSC_TRUE;
613:       }
614:     }
615:   }

617:   /* only first processor opens file if writeable */
618:   if (!rank || type == PETSC_FILE_RDONLY) {

620:     if (type == PETSC_FILE_RDONLY){
621:       /* possibly get the file from remote site or compressed file */
622:       PetscFileRetrieve(viewer->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
623:       fname = bname;
624:       if (!rank && !found) {
625:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
626:       } else if (!found) {
627:         PetscLogInfo((viewer,"PetscViewerSetFilename_Binary:Nonzero processor did not locate readonly file\n"));
628:         fname = 0;
629:       }
630:     } else {
631:       fname = vbinary->filename;
632:     }

634: #if defined(PETSC_HAVE_O_BINARY)
635:     if (type == PETSC_FILE_CREATE) {
636:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
637:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
638:       }
639:     } else if (type == PETSC_FILE_RDONLY && fname) {
640:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
641:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
642:       }
643:     } else if (type == PETSC_FILE_WRONLY) {
644:       if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
645:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
646:       }
647:     } else if (fname) {
648:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
649:     }
650: #else
651:     if (type == PETSC_FILE_CREATE) {
652:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
653:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
654:       }
655:     } else if (type == PETSC_FILE_RDONLY && fname) {
656:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
657:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
658:       }
659:     } else if (type == PETSC_FILE_WRONLY) {
660:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
661:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
662:       }
663:     } else if (fname) {
664:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
665:     }
666: #endif
667:   } else vbinary->fdes = -1;
668:   viewer->format = PETSC_VIEWER_NOFORMAT;

670:   /* 
671:       try to open info file: all processors open this file if read only
672:   */
673:   if (!rank || type == PETSC_FILE_RDONLY) {
674:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
675: 
676:     PetscStrcpy(infoname,name);
677:     /* remove .gz if it ends library name */
678:     PetscStrstr(infoname,".gz",&gz);
679:     if (gz) {
680:       PetscStrlen(gz,&len);
681:       if (len == 3) {
682:         *gz = 0;
683:       }
684:     }
685: 
686:     PetscStrcat(infoname,".info");
687:     PetscFixFilename(infoname,iname);
688:     if (type == PETSC_FILE_RDONLY) {
689:       PetscFileRetrieve(viewer->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
690:       if (found) {
691:         vbinary->fdes_info = fopen(infoname,"r");
692:         if (vbinary->fdes_info) {
693:           PetscViewerBinaryLoadInfo(viewer);
694:           fclose(vbinary->fdes_info);
695:         }
696:         vbinary->fdes_info = fopen(infoname,"r");
697:       }
698:     } else if (!vbinary->skipinfo) {
699:       vbinary->fdes_info = fopen(infoname,"w");
700:       if (!vbinary->fdes_info) {
701:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
702:       }
703:     }
704:   }

706: #if defined(PETSC_USE_LOG)
707:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
708: #endif
709:   return(0);
710: }

716: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_Binary(PetscViewer v)
717: {
718:   PetscErrorCode     ierr;
719:   PetscViewer_Binary *vbinary;

722:   PetscNew(PetscViewer_Binary,&vbinary);
723:   v->data            = (void*)vbinary;
724:   v->ops->destroy    = PetscViewerDestroy_Binary;
725:   v->ops->flush      = 0;
726:   v->iformat         = 0;
727:   vbinary->fdes_info = 0;
728:   vbinary->fdes      = 0;
729:   vbinary->skipinfo        = PETSC_FALSE;
730:   vbinary->skipoptions     = PETSC_TRUE;
731:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
732:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
733:   vbinary->btype           = (PetscViewerFileType) -1;
734:   vbinary->storecompressed = PETSC_FALSE;
735:   vbinary->filename        = 0;

737:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerSetFilename_C",
738:                                     "PetscViewerSetFilename_Binary",
739:                                      PetscViewerSetFilename_Binary);
740:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerSetFileType_C",
741:                                     "PetscViewerSetFileType_Binary",
742:                                      PetscViewerSetFileType_Binary);
743:   return(0);
744: }


748: /* ---------------------------------------------------------------------*/
749: /*
750:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
751:   is attached to a communicator, in this case the attribute is a PetscViewer.
752: */
753: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

757: /*@C
758:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 
759:                      in a communicator.

761:      Collective on MPI_Comm

763:      Input Parameter:
764: .    comm - the MPI communicator to share the binary PetscViewer
765:     
766:      Level: intermediate

768:    Options Database Keys:
769: $    -viewer_binary_filename <name>

771:    Environmental variables:
772: -   PETSC_VIEWER_BINARY_FILENAME

774:      Notes:
775:      Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 
776:      an error code.  The binary PetscViewer is usually used in the form
777: $       XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));

779: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
780:           PetscViewerDestroy()
781: @*/
782: PetscViewer PETSC_DLLEXPORT PETSC_VIEWER_BINARY_(MPI_Comm comm)
783: {
785:   PetscTruth     flg;
786:   PetscViewer    viewer;
787:   char           fname[PETSC_MAX_PATH_LEN];

790:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
791:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
792:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
793:   }
794:   MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
795:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
796:   if (!flg) { /* PetscViewer not yet created */
797:     PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
798:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
799:     if (!flg) {
800:       PetscStrcpy(fname,"binaryoutput");
801:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
802:     }
803:     PetscViewerBinaryOpen(comm,fname,PETSC_FILE_CREATE,&viewer);
804:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
805:     PetscObjectRegisterDestroy((PetscObject)viewer);
806:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
807:     MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
808:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
809:   }
810:   PetscFunctionReturn(viewer);
811: }