Actual source code: binv.c

  1: #define PETSC_DLL
 2:  #include src/sys/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:   PetscFileMode 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(((PetscObject)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(((PetscObject)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  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  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  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  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  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:   PetscMPIInt        rank;
228:   int                err;

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

262: /*@
263:    PetscViewerBinaryCreate - Create a binary viewer.

265:    Collective on MPI_Comm

267:    Input Parameters:
268: .  comm - MPI communicator

270:    Output Parameter:
271: .  binv - PetscViewer for binary input/output

273:    Level: beginner
274: @*/
275: PetscErrorCode  PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
276: {
278: 
280:   PetscViewerCreate(comm,binv);
281:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
282:   return(0);
283: }

287: /*@C
288:    PetscViewerBinaryOpen - Opens a file for binary input/output.

290:    Collective on MPI_Comm

292:    Input Parameters:
293: +  comm - MPI communicator
294: .  name - name of file 
295: -  type - type of file
296: $    FILE_MODE_WRITE - create new file for binary output
297: $    FILE_MODE_READ - open existing file for binary input
298: $    FILE_MODE_APPEND - open existing file for binary output

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

303:    Level: beginner

305:    Note:
306:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

314:     For writing files it only opens the file on processor 0 in the communicator.
315:     For readable files it opens the file on all nodes that have the file. If 
316:     node 0 does not have the file it generates an error even if other nodes
317:     do have the file.

319:    Concepts: binary files
320:    Concepts: PetscViewerBinary^creating
321:    Concepts: gzip
322:    Concepts: accessing remote file
323:    Concepts: remote file

325: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
326:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
327:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
328: @*/
329: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
330: {
332: 
334:   PetscViewerCreate(comm,binv);
335:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
336:   PetscViewerFileSetMode(*binv,type);
337:   PetscViewerFileSetName(*binv,name);
338:   return(0);
339: }

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

346:    Collective on MPI_Comm

348:    Input Parameters:
349: +  viewer - the binary viewer
350: .  data - location to write the data
351: .  count - number of items of data to read
352: -  datatype - type of data to read

354:    Level: beginner

356:    Concepts: binary files

358: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
359:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
360:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
361: @*/
362: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
363: {
364:   PetscErrorCode     ierr;
365:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

367:   PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
368:   return(0);
369: }

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

376:    Collective on MPI_Comm

378:    Input Parameters:
379: +  viewer - the binary viewer
380: .  data - location of data
381: .  count - number of items of data to read
382: .  istemp - data may be overwritten
383: -  datatype - type of data to read

385:    Level: beginner

387:    Concepts: binary files

389: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
390:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
391:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
392: @*/
393: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
394: {
395:   PetscErrorCode     ierr;
396:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

398:   PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
399:   return(0);
400: }

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

407:    Collective on MPI_Comm

409:    Input Parameters:
410: +  viewer - the binary viewer
411: -  data - location of the array of strings


414:    Level: intermediate

416:    Concepts: binary files

418:     Notes: array of strings is null terminated

420: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
421:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
422:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
423: @*/
424: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
425: {
426:   PetscErrorCode     ierr;
427:   PetscInt           i,n = 0,*sizes;

429:   /* count number of strings */
430:   while (data[n++]);
431:   n--;
432:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
433:   sizes[0] = n;
434:   for (i=0; i<n; i++) {
435:     size_t tmp;
436:     PetscStrlen(data[i],&tmp);
437:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
438:   }
439:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
440:   for (i=0; i<n; i++) {
441:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
442:   }
443:   PetscFree(sizes);
444:   return(0);
445: }

447: /*@C
448:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

450:    Collective on MPI_Comm

452:    Input Parameter:
453: .  viewer - the binary viewer

455:    Output Parameter:
456: .  data - location of the array of strings

458:    Level: intermediate

460:    Concepts: binary files

462:     Notes: array of strings is null terminated

464: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
465:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
466:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
467: @*/
468: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
469: {
470:   PetscErrorCode     ierr;
471:   PetscInt           i,n,*sizes,N = 0;

473:   /* count number of strings */
474:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
475:   PetscMalloc(n*sizeof(PetscInt),&sizes);
476:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
477:   for (i=0; i<n; i++) {
478:     N += sizes[i];
479:   }
480:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
481:   (*data)[0] = (char*)((*data) + n + 1);
482:   for (i=1; i<n; i++) {
483:     (*data)[i] = (*data)[i-1] + sizes[i-1];
484:   }
485:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
486:   (*data)[n] = 0;
487:   PetscFree(sizes);
488:   return(0);
489: }

493: /*@C
494:      PetscViewerFileGetMode - Gets the type of file to be open

496:     Collective on PetscViewer

498:   Input Parameter:
499: .  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer

501:   Output Parameter:
502: .  type - type of file
503: $    FILE_MODE_WRITE - create new file for binary output
504: $    FILE_MODE_READ - open existing file for binary input
505: $    FILE_MODE_APPEND - open existing file for binary output

507:   Level: advanced

509: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

511: @*/
512: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
513: {
514:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);

519:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
520:   if (f) {
521:     (*f)(viewer,type);
522:   }
523:   return(0);
524: }

528: /*@C
529:      PetscViewerFileSetMode - Sets the type of file to be open

531:     Collective on PetscViewer

533:   Input Parameters:
534: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
535: -  type - type of file
536: $    FILE_MODE_WRITE - create new file for binary output
537: $    FILE_MODE_READ - open existing file for binary input
538: $    FILE_MODE_APPEND - open existing file for binary output

540:   Level: advanced

542: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

544: @*/
545: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
546: {
547:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);

551:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
552:   if (f) {
553:     (*f)(viewer,type);
554:   }
555:   return(0);
556: }

561: PetscErrorCode  PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
562: {
563:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

566:   *type = vbinary->btype;
567:   return(0);
568: }

574: PetscErrorCode  PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
575: {
576:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

579:   vbinary->btype = type;
580:   return(0);
581: }

586: /*@
587:     PetscViewerBinaryLoadInfo - Loads options from the name.info file
588:        if it exists.

590:    Collective on PetscViewer

592:   Input Parameter:
593: .    viewer - the binary viewer whose options you wish to load

595:    Level: developer

597: @*/
598: PetscErrorCode  PetscViewerBinaryLoadInfo(PetscViewer viewer)
599: {
600:   FILE               *file;
601:   char               string[256],*first,*second,*final;
602:   size_t             len;
603:   PetscErrorCode     ierr;
604:   PetscToken         token;
605:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

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

610:   PetscViewerBinaryGetInfoPointer(viewer,&file);
611:   if (!file) return(0);

613:   /* read rows of the file adding them to options database */
614:   while (fgets(string,256,file)) {
615:     /* Comments are indicated by #, ! or % in the first column */
616:     if (string[0] == '#') continue;
617:     if (string[0] == '!') continue;
618:     if (string[0] == '%') continue;
619:     PetscTokenCreate(string,' ',&token);
620:     PetscTokenFind(token,&first);
621:     PetscTokenFind(token,&second);
622:     if (first && first[0] == '-') {
623:       PetscTruth wrongtype;
624:       /*
625:          Check for -mat_complex or -mat_double
626:       */
627: #if defined(PETSC_USE_COMPLEX)
628:       PetscStrncmp(first,"-mat_double",11,&wrongtype);
629:       if (wrongtype) {
630:         SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading double number matrix with complex number code");
631:       }
632: #else
633:       PetscStrncmp(first,"-mat_complex",12,&wrongtype);
634:       if (wrongtype) {
635:         SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Loading complex number matrix with double number code");
636:       }
637: #endif

639:       if (second) {final = second;} else {final = first;}
640:       PetscStrlen(final,&len);
641:       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
642:         len--; final[len] = 0;
643:       }
644:       PetscOptionsSetValue(first,second);
645:     }
646:     PetscTokenDestroy(token);
647:   }
648:   return(0);
649: }

651: /*
652:         Actually opens the file 
653: */
657: PetscErrorCode  PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
658: {
659:   PetscMPIInt         rank;
660:   PetscErrorCode      ierr;
661:   size_t              len;
662:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
663:   const char          *fname;
664:   char                bname[PETSC_MAX_PATH_LEN],*gz;
665:   PetscTruth          found;
666:   PetscFileMode       type = vbinary->btype;
667:   int                 err;

670:   if (type == (PetscFileMode) -1) {
671:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
672:   }
673:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
674:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

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

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

681:   /* if ends in .gz strip that off and note user wants file compressed */
682:   vbinary->storecompressed = PETSC_FALSE;
683:   if (!rank && type == FILE_MODE_WRITE) {
684:     /* remove .gz if it ends library name */
685:     PetscStrstr(vbinary->filename,".gz",&gz);
686:     if (gz) {
687:       PetscStrlen(gz,&len);
688:       if (len == 3) {
689:         *gz = 0;
690:         vbinary->storecompressed = PETSC_TRUE;
691:       }
692:     }
693:   }

695:   /* only first processor opens file if writeable */
696:   if (!rank || type == FILE_MODE_READ) {

698:     if (type == FILE_MODE_READ){
699:       /* possibly get the file from remote site or compressed file */
700:       PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
701:       fname = bname;
702:       if (!rank && !found) {
703:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
704:       } else if (!found) {
705:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
706:         fname = 0;
707:       }
708:     } else {
709:       fname = vbinary->filename;
710:     }

712: #if defined(PETSC_HAVE_O_BINARY)
713:     if (type == FILE_MODE_WRITE) {
714:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
715:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
716:       }
717:     } else if (type == FILE_MODE_READ && fname) {
718:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
719:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
720:       }
721:     } else if (type == FILE_MODE_APPEND) {
722:       if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
723:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
724:       }
725:     } else if (fname) {
726:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
727:     }
728: #else
729:     if (type == FILE_MODE_WRITE) {
730:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
731:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
732:       }
733:     } else if (type == FILE_MODE_READ && fname) {
734:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
735:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
736:       }
737:     } else if (type == FILE_MODE_APPEND) {
738:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
739:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
740:       }
741:     } else if (fname) {
742:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
743:     }
744: #endif
745:   } else vbinary->fdes = -1;
746:   viewer->format = PETSC_VIEWER_NOFORMAT;

748:   /* 
749:       try to open info file: all processors open this file if read only
750:   */
751:   if (!rank || type == FILE_MODE_READ) {
752:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
753: 
754:     PetscStrcpy(infoname,name);
755:     /* remove .gz if it ends library name */
756:     PetscStrstr(infoname,".gz",&gz);
757:     if (gz) {
758:       PetscStrlen(gz,&len);
759:       if (len == 3) {
760:         *gz = 0;
761:       }
762:     }
763: 
764:     PetscStrcat(infoname,".info");
765:     PetscFixFilename(infoname,iname);
766:     if (type == FILE_MODE_READ) {
767:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
768:       if (found) {
769:         vbinary->fdes_info = fopen(infoname,"r");
770:         if (vbinary->fdes_info) {
771:           PetscViewerBinaryLoadInfo(viewer);
772:           err  = fclose(vbinary->fdes_info);
773:           if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
774:         }
775:         vbinary->fdes_info = fopen(infoname,"r");
776:       }
777:     } else if (!vbinary->skipinfo) {
778:       vbinary->fdes_info = fopen(infoname,"w");
779:       if (!vbinary->fdes_info) {
780:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
781:       }
782:     }
783:   }

785: #if defined(PETSC_USE_LOG)
786:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
787: #endif
788:   return(0);
789: }

795: PetscErrorCode  PetscViewerCreate_Binary(PetscViewer v)
796: {
797:   PetscErrorCode     ierr;
798:   PetscViewer_Binary *vbinary;

801:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
802:   v->data            = (void*)vbinary;
803:   v->ops->destroy    = PetscViewerDestroy_Binary;
804:   v->ops->flush      = 0;
805:   v->iformat         = 0;
806:   vbinary->fdes_info = 0;
807:   vbinary->fdes      = 0;
808:   vbinary->skipinfo        = PETSC_FALSE;
809:   vbinary->skipoptions     = PETSC_TRUE;
810:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
811:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
812:   vbinary->btype           = (PetscFileMode) -1;
813:   vbinary->storecompressed = PETSC_FALSE;
814:   vbinary->filename        = 0;

816:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
817:                                     "PetscViewerFileSetName_Binary",
818:                                      PetscViewerFileSetName_Binary);
819:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
820:                                     "PetscViewerFileSetMode_Binary",
821:                                      PetscViewerFileSetMode_Binary);
822:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
823:                                     "PetscViewerFileGetMode_Binary",
824:                                      PetscViewerFileGetMode_Binary);
825:   return(0);
826: }


830: /* ---------------------------------------------------------------------*/
831: /*
832:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
833:   is attached to a communicator, in this case the attribute is a PetscViewer.
834: */
835: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

839: /*@C
840:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 
841:                      in a communicator.

843:      Collective on MPI_Comm

845:      Input Parameter:
846: .    comm - the MPI communicator to share the binary PetscViewer
847:     
848:      Level: intermediate

850:    Options Database Keys:
851: $    -viewer_binary_filename <name>

853:    Environmental variables:
854: -   PETSC_VIEWER_BINARY_FILENAME

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

861: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
862:           PetscViewerDestroy()
863: @*/
864: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
865: {
867:   PetscTruth     flg;
868:   PetscViewer    viewer;
869:   char           fname[PETSC_MAX_PATH_LEN];

872:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
873:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
874:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
875:   }
876:   MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
877:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
878:   if (!flg) { /* PetscViewer not yet created */
879:     PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
880:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
881:     if (!flg) {
882:       PetscStrcpy(fname,"binaryoutput");
883:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
884:     }
885:     PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
886:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
887:     PetscObjectRegisterDestroy((PetscObject)viewer);
888:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
889:     MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
890:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
891:   }
892:   PetscFunctionReturn(viewer);
893: }