Actual source code: binv.c

  1: #define PETSC_DLL
 2:  #include private/viewerimpl.h
  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

 11: typedef struct  {
 12:   int           fdes;            /* file descriptor, ignored if using MPI IO */
 13: #if defined(PETSC_HAVE_MPIIO)
 14:   PetscTruth    MPIIO;
 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:   PetscTruth    storecompressed; /* gzip the write binary file when closing it*/
 21:   char          *filename;
 22:   PetscTruth    skipinfo;        /* Don't create info file for writing; don't use for reading */
 23:   PetscTruth    skipoptions;     /* don't use PETSc options database when loading */
 24:   PetscInt      flowcontrol;     /* allow only <flowcontrol> messages outstanding at a time while doing IO */
 25: } PetscViewer_Binary;

 29: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
 30: {
 31:   int                rank;
 32:   PetscErrorCode     ierr;
 33:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;

 36:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
 37:   if (!rank) {
 38:     PetscViewerCreate(PETSC_COMM_SELF,outviewer);
 39:     PetscViewerSetType(*outviewer,PETSC_VIEWER_BINARY);
 40:     obinary = (PetscViewer_Binary*)(*outviewer)->data;
 41:     PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
 42:   } else {
 43:     *outviewer = 0;
 44:   }
 45:   return(0);
 46: }

 50: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
 51: {
 53:   PetscErrorCode rank;

 56:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
 57:   if (!rank) {
 58:     PetscFree((*outviewer)->data);
 59:     PetscHeaderDestroy(*outviewer);
 60:   }
 61:   return(0);
 62: }

 64: #if defined(PETSC_HAVE_MPIIO)
 67: /*@C
 68:     PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()

 70:     Not Collective

 72:     Input Parameter:
 73: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

 75:     Output Parameter:
 76: .    off - the current offset

 78:     Level: advanced

 80:     Fortran Note:
 81:     This routine is not supported in Fortran.

 83:     Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.

 85:   Concepts: file descriptor^getting
 86:   Concepts: PetscViewerBinary^accessing file descriptor

 88: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
 89: @*/
 90: PetscErrorCode  PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
 91: {
 92:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

 95:   *off = vbinary->moff;
 96:   return(0);
 97: }

101: /*@C
102:     PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()

104:     Not Collective

106:     Input Parameters:
107: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
108: -    off - the addition to the offset

110:     Level: advanced

112:     Fortran Note:
113:     This routine is not supported in Fortran.

115:     Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()

117:   Concepts: file descriptor^getting
118:   Concepts: PetscViewerBinary^accessing file descriptor

120: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
121: @*/
122: PetscErrorCode  PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
123: {
124:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

127:   vbinary->moff += off;
128:   return(0);
129: }

133: /*@C
134:     PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.

136:     Not Collective

138:     Input Parameter:
139: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

141:     Output Parameter:
142: .   fdes - file descriptor

144:     Level: advanced

146:     Fortran Note:
147:     This routine is not supported in Fortran.

149:   Concepts: file descriptor^getting
150:   Concepts: PetscViewerBinary^accessing file descriptor

152: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
153: @*/
154: PetscErrorCode  PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
155: {
156:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

159:   *fdes = vbinary->mfdes;
160:   return(0);
161: }

165: /*@C
166:     PetscViewerBinaryGetMPIIO - Returns PETSC_TRUE if the binary viewer is an MPI viewer.

168:     Not Collective

170:     Input Parameter:
171: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

173:     Output Parameter:
174: -   flg - PETSC_TRUE if MPI IO is being used

176:     Level: advanced

178:     Fortran Note:
179:     This routine is not supported in Fortran.

181:   Concepts: file descriptor^getting
182:   Concepts: PetscViewerBinary^accessing file descriptor

184: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
185: @*/
186: PetscErrorCode  PetscViewerBinaryGetMPIIO(PetscViewer viewer,PetscTruth *flg)
187: {
188:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

191:   *flg = vbinary->MPIIO;
192:   return(0);
193: }
194: #endif

198: /*@C
199:     PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes

201:     Not Collective

203:     Input Parameter:
204: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

206:     Output Parameter:
207: .   fc - the number of messages

209:     Level: advanced

211: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()

213: @*/
214: PetscErrorCode  PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
215: {
216:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

219:   *fc = vbinary->flowcontrol;
220:   return(0);
221: }

225: /*@C
226:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

228:     Not Collective

230:     Input Parameter:
231: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

233:     Output Parameter:
234: .   fdes - file descriptor

236:     Level: advanced

238:     Notes:
239:       For writable binary PetscViewers, the descriptor will only be valid for the 
240:     first processor in the communicator that shares the PetscViewer. For readable 
241:     files it will only be valid on nodes that have the file. If node 0 does not
242:     have the file it generates an error even if another node does have the file.
243:  
244:     Fortran Note:
245:     This routine is not supported in Fortran.

247:   Concepts: file descriptor^getting
248:   Concepts: PetscViewerBinary^accessing file descriptor

250: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
251: @*/
252: PetscErrorCode  PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
253: {
254:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

257:   *fdes = vbinary->fdes;
258:   return(0);
259: }

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

266:     Not Collective

268:     Input Paramter:
269: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

271:     Options Database Key:
272: .   -viewer_binary_skip_info

274:     Level: advanced

276:     Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then 
277:     you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
278:     viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().

280:     The .info contains meta information about the data in the binary file, for example the block size if it was
281:     set for a vector or matrix.

283:    Concepts: PetscViewerBinary^accessing info file

285: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
286:           PetscViewerBinaryGetSkipOptions()
287: @*/
288: PetscErrorCode  PetscViewerBinarySkipInfo(PetscViewer viewer)
289: {
290:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

293:   vbinary->skipinfo = PETSC_TRUE;
294:   return(0);
295: }

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

302:     Not Collective

304:     Input Parameters:
305: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
306: -   skip - PETSC_TRUE means do not use

308:     Options Database Key:
309: .   -viewer_binary_skip_options

311:     Level: advanced

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

315:    Concepts: PetscViewerBinary^accessing info file

317: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
318:           PetscViewerBinaryGetSkipOptions()
319: @*/
320: PetscErrorCode  PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscTruth skip)
321: {
322:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

325:   vbinary->skipoptions = skip;
326:   return(0);
327: }

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

334:     Not Collective

336:     Input Parameter:
337: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

339:     Output Parameter:
340: .   skip - PETSC_TRUE means do not use

342:     Level: advanced

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

346:    Concepts: PetscViewerBinary^accessing info file

348: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
349:           PetscViewerBinarySetSkipOptions()
350: @*/
351: PetscErrorCode  PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscTruth *skip)
352: {
353:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

356:   *skip = vbinary->skipoptions;
357:   return(0);
358: }

362: /*@C
363:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
364:           info file associated with a binary file.

366:     Not Collective

368:     Input Parameter:
369: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

371:     Output Parameter:
372: .   file - file pointer

374:     Level: advanced

376:     Notes:
377:       For writable binary PetscViewers, the descriptor will only be valid for the 
378:     first processor in the communicator that shares the PetscViewer.
379:  
380:     Fortran Note:
381:     This routine is not supported in Fortran.

383:   Concepts: PetscViewerBinary^accessing info file

385: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
386: @*/
387: PetscErrorCode  PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
388: {
389:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

392:   *file = vbinary->fdes_info;
393:   return(0);
394: }

398: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
399: {
400:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
401:   PetscErrorCode     ierr;
402:   PetscMPIInt        rank;
403:   int                err;

406:   MPI_Comm_rank(((PetscObject)v)->comm,&rank);
407:   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
408:     close(vbinary->fdes);
409:     if (!rank && vbinary->storecompressed) {
410:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
411:       FILE *fp;
412:       /* compress the file */
413:       PetscStrcpy(par,"gzip -f ");
414:       PetscStrcat(par,vbinary->filename);
415: #if defined(PETSC_HAVE_POPEN)
416:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
417:       if (fgets(buf,1024,fp)) {
418:         SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
419:       }
420:       PetscPClose(PETSC_COMM_SELF,fp);
421: #else
422:       SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
423: #endif
424:     }
425:   }
426:   if (vbinary->fdes_info) {
427:     err = fclose(vbinary->fdes_info);
428:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
429:   }
430:   PetscStrfree(vbinary->filename);
431:   PetscFree(vbinary);
432:   return(0);
433: }

435: #if defined(PETSC_HAVE_MPIIO)
438: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
439: {
440:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
441:   PetscErrorCode     ierr;
442:   int                err;

445:   if (vbinary->mfdes) {
446:     MPI_File_close(&vbinary->mfdes);
447:   }
448:   if (vbinary->fdes_info) {
449:     err = fclose(vbinary->fdes_info);
450:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
451:   }
452:   PetscStrfree(vbinary->filename);
453:   PetscFree(vbinary);
454:   return(0);
455: }
456: #endif

460: /*@
461:    PetscViewerBinaryCreate - Create a binary viewer.

463:    Collective on MPI_Comm

465:    Input Parameters:
466: .  comm - MPI communicator

468:    Output Parameter:
469: .  binv - PetscViewer for binary input/output

471:    Level: beginner
472: @*/
473: PetscErrorCode  PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
474: {
476: 
478:   PetscViewerCreate(comm,binv);
479:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
480:   return(0);
481: }

485: /*@C
486:    PetscViewerBinaryOpen - Opens a file for binary input/output.

488:    Collective on MPI_Comm

490:    Input Parameters:
491: +  comm - MPI communicator
492: .  name - name of file 
493: -  type - type of file
494: $    FILE_MODE_WRITE - create new file for binary output
495: $    FILE_MODE_READ - open existing file for binary input
496: $    FILE_MODE_APPEND - open existing file for binary output

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

501:     Options Database Keys:
502: +    -viewer_binary_skip_info
503: -    -viewer_binary_skip_options

505:    Level: beginner

507:    Note:
508:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

516:     For writing files it only opens the file on processor 0 in the communicator.
517:     For readable files it opens the file on all nodes that have the file. If 
518:     node 0 does not have the file it generates an error even if other nodes
519:     do have the file.

521:    Concepts: binary files
522:    Concepts: PetscViewerBinary^creating
523:    Concepts: gzip
524:    Concepts: accessing remote file
525:    Concepts: remote file

527: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
528:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
529:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
530: @*/
531: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
532: {
534: 
536:   PetscViewerCreate(comm,binv);
537:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
538:   PetscViewerFileSetMode(*binv,type);
539:   PetscViewerFileSetName(*binv,name);
540:   return(0);
541: }

543: #if defined(PETSC_HAVE_MPIIO)
546: static PetscErrorCode  PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth write)
547: {
548:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
549:   PetscErrorCode     ierr;
550:   MPI_Datatype       mdtype;
551:   PetscMPIInt        cnt = PetscMPIIntCast(count);
552:   MPI_Status         status;
553:   MPI_Aint           ul,dsize;

556:   PetscDataTypeToMPIDataType(dtype,&mdtype);
557:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
558:   if (write) {
559:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
560:   } else {
561:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
562:   }
563:   MPI_Type_get_extent(mdtype,&ul,&dsize);
564:   vbinary->moff += dsize*cnt;
565:   return(0);
566: }
567: #endif

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

574:    Collective on MPI_Comm

576:    Input Parameters:
577: +  viewer - the binary viewer
578: .  data - location to write the data
579: .  count - number of items of data to read
580: -  datatype - type of data to read

582:    Level: beginner

584:    Concepts: binary files

586: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
587:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
588:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
589: @*/
590: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
591: {
592:   PetscErrorCode     ierr;
593:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

595: #if defined(PETSC_HAVE_MPIIO)
596:   if (vbinary->MPIIO) {
597:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
598:   } else {
599: #endif
600:     PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
601: #if defined(PETSC_HAVE_MPIIO)
602:   }
603: #endif
604:   return(0);
605: }


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

613:    Collective on MPI_Comm

615:    Input Parameters:
616: +  viewer - the binary viewer
617: .  data - location of data
618: .  count - number of items of data to read
619: .  istemp - data may be overwritten
620: -  datatype - type of data to read

622:    Level: beginner

624:    Notes: because byte-swapping may be done on the values in data it cannot be declared const

626:    Concepts: binary files

628: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
629:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
630:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
631: @*/
632: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
633: {
634:   PetscErrorCode     ierr;
635:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

638: #if defined(PETSC_HAVE_MPIIO)
639:   if (vbinary->MPIIO) {
640:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
641:   } else {
642: #endif
643:     PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
644: #if defined(PETSC_HAVE_MPIIO)
645:   }
646: #endif
647:   return(0);
648: }

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

655:    Collective on MPI_Comm

657:    Input Parameters:
658: +  viewer - the binary viewer
659: -  data - location of the array of strings


662:    Level: intermediate

664:    Concepts: binary files

666:     Notes: array of strings is null terminated

668: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
669:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
670:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
671: @*/
672: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
673: {
674:   PetscErrorCode     ierr;
675:   PetscInt           i,n = 0,*sizes;

677:   /* count number of strings */
678:   while (data[n++]);
679:   n--;
680:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
681:   sizes[0] = n;
682:   for (i=0; i<n; i++) {
683:     size_t tmp;
684:     PetscStrlen(data[i],&tmp);
685:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
686:   }
687:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
688:   for (i=0; i<n; i++) {
689:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
690:   }
691:   PetscFree(sizes);
692:   return(0);
693: }

695: /*@C
696:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

698:    Collective on MPI_Comm

700:    Input Parameter:
701: .  viewer - the binary viewer

703:    Output Parameter:
704: .  data - location of the array of strings

706:    Level: intermediate

708:    Concepts: binary files

710:     Notes: array of strings is null terminated

712: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
713:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
714:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
715: @*/
716: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
717: {
718:   PetscErrorCode     ierr;
719:   PetscInt           i,n,*sizes,N = 0;

721:   /* count number of strings */
722:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
723:   PetscMalloc(n*sizeof(PetscInt),&sizes);
724:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
725:   for (i=0; i<n; i++) {
726:     N += sizes[i];
727:   }
728:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
729:   (*data)[0] = (char*)((*data) + n + 1);
730:   for (i=1; i<n; i++) {
731:     (*data)[i] = (*data)[i-1] + sizes[i-1];
732:   }
733:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
734:   (*data)[n] = 0;
735:   PetscFree(sizes);
736:   return(0);
737: }

741: /*@C
742:      PetscViewerFileGetMode - Gets the type of file to be open

744:     Collective on PetscViewer

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

749:   Output Parameter:
750: .  type - type of file
751: $    FILE_MODE_WRITE - create new file for binary output
752: $    FILE_MODE_READ - open existing file for binary input
753: $    FILE_MODE_APPEND - open existing file for binary output

755:   Level: advanced

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

759: @*/
760: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
761: {
762:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);

767:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
768:   if (f) {
769:     (*f)(viewer,type);
770:   }
771:   return(0);
772: }

776: /*@
777:      PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
778:         before PetscViewerFileSetName()

780:     Collective on PetscViewer

782:   Input Parameters:
783: .  viewer - the PetscViewer; must be a binary

785:    Notes: turns off the default usage of the .info file since that is not scalable

787:   Level: advanced

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

791: @*/
792: PetscErrorCode  PetscViewerBinarySetMPIIO(PetscViewer viewer)
793: {
794:   PetscErrorCode ierr,(*f)(PetscViewer);

798:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
799:   if (f) {
800:     (*f)(viewer);
801:   }
802:   return(0);
803: }


806: /*@C
807:      PetscViewerFileSetMode - Sets the type of file to be open

809:     Collective on PetscViewer

811:   Input Parameters:
812: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
813: -  type - type of file
814: $    FILE_MODE_WRITE - create new file for binary output
815: $    FILE_MODE_READ - open existing file for binary input
816: $    FILE_MODE_APPEND - open existing file for binary output

818:   Level: advanced

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

822: @*/
823: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
824: {
825:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);

829:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
830:   if (f) {
831:     (*f)(viewer,type);
832:   }
833:   return(0);
834: }

839: PetscErrorCode  PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
840: {
841:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

844:   *type = vbinary->btype;
845:   return(0);
846: }

852: PetscErrorCode  PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
853: {
854:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

857:   vbinary->btype = type;
858:   return(0);
859: }

862: /*
863:         Actually opens the file 
864: */
868: PetscErrorCode  PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
869: {
870:   PetscMPIInt         rank;
871:   PetscErrorCode      ierr;
872:   size_t              len;
873:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
874:   const char          *fname;
875:   char                bname[PETSC_MAX_PATH_LEN],*gz;
876:   PetscTruth          found;
877:   PetscFileMode       type = vbinary->btype;

880:   if (type == (PetscFileMode) -1) {
881:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
882:   }
883:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
884:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

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

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

891:   /* if ends in .gz strip that off and note user wants file compressed */
892:   vbinary->storecompressed = PETSC_FALSE;
893:   if (!rank && type == FILE_MODE_WRITE) {
894:     /* remove .gz if it ends library name */
895:     PetscStrstr(vbinary->filename,".gz",&gz);
896:     if (gz) {
897:       PetscStrlen(gz,&len);
898:       if (len == 3) {
899:         *gz = 0;
900:         vbinary->storecompressed = PETSC_TRUE;
901:       }
902:     }
903:   }

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

908:     if (type == FILE_MODE_READ){
909:       /* possibly get the file from remote site or compressed file */
910:       PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
911:       fname = bname;
912:       if (!rank && !found) {
913:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
914:       } else if (!found) {
915:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
916:         fname = 0;
917:       }
918:     } else {
919:       fname = vbinary->filename;
920:     }

922: #if defined(PETSC_HAVE_O_BINARY)
923:     if (type == FILE_MODE_WRITE) {
924:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
925:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
926:       }
927:     } else if (type == FILE_MODE_READ && fname) {
928:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
929:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
930:       }
931:     } else if (type == FILE_MODE_APPEND) {
932:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
933:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
934:       }
935:     } else if (fname) {
936:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
937:     }
938: #else
939:     if (type == FILE_MODE_WRITE) {
940:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
941:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
942:       }
943:     } else if (type == FILE_MODE_READ && fname) {
944:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
945:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
946:       }
947:     } else if (type == FILE_MODE_APPEND) {
948:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
949:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
950:       }
951:     } else if (fname) {
952:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
953:     }
954: #endif
955:   } else vbinary->fdes = -1;
956:   viewer->format = PETSC_VIEWER_NOFORMAT;

958:   /* 
959:       try to open info file: all processors open this file if read only
960:   */
961:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
962:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
963: 
964:     PetscStrcpy(infoname,name);
965:     /* remove .gz if it ends library name */
966:     PetscStrstr(infoname,".gz",&gz);
967:     if (gz) {
968:       PetscStrlen(gz,&len);
969:       if (len == 3) {
970:         *gz = 0;
971:       }
972:     }
973: 
974:     PetscStrcat(infoname,".info");
975:     PetscFixFilename(infoname,iname);
976:     if (type == FILE_MODE_READ) {
977:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
978:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
979:     } else {
980:       vbinary->fdes_info = fopen(infoname,"w");
981:       if (!vbinary->fdes_info) {
982:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
983:       }
984:     }
985:   }

987: #if defined(PETSC_USE_LOG)
988:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
989: #endif
990:   return(0);
991: }

994: #if defined(PETSC_HAVE_MPIIO)
998: PetscErrorCode  PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
999: {
1000:   PetscMPIInt         rank;
1001:   PetscErrorCode      ierr;
1002:   size_t              len;
1003:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
1004:   char                *gz;
1005:   PetscTruth          found;
1006:   PetscFileMode       type = vbinary->btype;

1009:   if (type == (PetscFileMode) -1) {
1010:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
1011:   }
1012:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1013:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

1015:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1016:   PetscStrallocpy(name,&vbinary->filename);
1017:   vbinary->storecompressed = PETSC_FALSE;


1020:   /* only first processor opens file if writeable */
1021:   if (type == FILE_MODE_READ) {
1022:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1023:   } else if (type == FILE_MODE_WRITE) {
1024:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1025:   }
1026:   viewer->format = PETSC_VIEWER_NOFORMAT;

1028:   /* 
1029:       try to open info file: all processors open this file if read only

1031:       Below is identical code to the code for Binary above, should be put in seperate routine
1032:   */
1033:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1034:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1035: 
1036:     PetscStrcpy(infoname,name);
1037:     /* remove .gz if it ends library name */
1038:     PetscStrstr(infoname,".gz",&gz);
1039:     if (gz) {
1040:       PetscStrlen(gz,&len);
1041:       if (len == 3) {
1042:         *gz = 0;
1043:       }
1044:     }
1045: 
1046:     PetscStrcat(infoname,".info");
1047:     PetscFixFilename(infoname,iname);
1048:     if (type == FILE_MODE_READ) {
1049:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1050:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1051:     } else {
1052:       vbinary->fdes_info = fopen(infoname,"w");
1053:       if (!vbinary->fdes_info) {
1054:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1055:       }
1056:     }
1057:   }

1059: #if defined(PETSC_USE_LOG)
1060:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1061: #endif
1062:   return(0);
1063: }

1069: PetscErrorCode  PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1070: {
1071:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1072:   PetscErrorCode     ierr;

1075:   if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1076:   viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1077:   vbinary->MPIIO       = PETSC_TRUE;
1078:   /*  vbinary->skipinfo    = PETSC_TRUE; */
1079:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1080:   return(0);
1081: }
1083: #endif

1088: PetscErrorCode  PetscViewerCreate_Binary(PetscViewer v)
1089: {
1090:   PetscErrorCode     ierr;
1091:   PetscViewer_Binary *vbinary;
1092: #if defined(PETSC_HAVE_MPIIO)
1093:   PetscTruth         useMPIIO = PETSC_FALSE;
1094: #endif

1097:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
1098:   v->data            = (void*)vbinary;
1099:   v->ops->destroy    = PetscViewerDestroy_Binary;
1100:   v->ops->flush      = 0;
1101:   v->iformat         = 0;
1102:   vbinary->fdes_info = 0;
1103:   vbinary->fdes      = 0;
1104:   vbinary->skipinfo        = PETSC_FALSE;
1105:   vbinary->skipoptions     = PETSC_TRUE;
1106:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1107:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1108:   vbinary->btype           = (PetscFileMode) -1;
1109:   vbinary->storecompressed = PETSC_FALSE;
1110:   vbinary->filename        = 0;
1111:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

1113:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1114:                                     "PetscViewerFileSetName_Binary",
1115:                                      PetscViewerFileSetName_Binary);
1116:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1117:                                     "PetscViewerFileSetMode_Binary",
1118:                                      PetscViewerFileSetMode_Binary);
1119:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1120:                                     "PetscViewerFileGetMode_Binary",
1121:                                      PetscViewerFileGetMode_Binary);
1122: #if defined(PETSC_HAVE_MPIIO)
1123:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1124:                                     "PetscViewerBinarySetMPIIO_Binary",
1125:                                      PetscViewerBinarySetMPIIO_Binary);
1126: 
1127:   PetscOptionsGetTruth(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1128:   if (useMPIIO) {
1129:     PetscViewerBinarySetMPIIO(v);
1130:   }
1131: #endif
1132:   return(0);
1133: }


1137: /* ---------------------------------------------------------------------*/
1138: /*
1139:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1140:   is attached to a communicator, in this case the attribute is a PetscViewer.
1141: */
1142: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1146: /*@C
1147:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 
1148:                      in a communicator.

1150:      Collective on MPI_Comm

1152:      Input Parameter:
1153: .    comm - the MPI communicator to share the binary PetscViewer
1154:     
1155:      Level: intermediate

1157:    Options Database Keys:
1158: +    -viewer_binary_filename <name>
1159: .    -viewer_binary_skip_info
1160: -    -viewer_binary_skip_options

1162:    Environmental variables:
1163: -   PETSC_VIEWER_BINARY_FILENAME

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

1170: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1171:           PetscViewerDestroy()
1172: @*/
1173: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
1174: {
1176:   PetscTruth     flg;
1177:   PetscViewer    viewer;
1178:   char           fname[PETSC_MAX_PATH_LEN];

1181:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1182:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1183:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1184:   }
1185:   MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1186:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1187:   if (!flg) { /* PetscViewer not yet created */
1188:     PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1189:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1190:     if (!flg) {
1191:       PetscStrcpy(fname,"binaryoutput");
1192:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1193:     }
1194:     PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1195:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1196:     PetscObjectRegisterDestroy((PetscObject)viewer);
1197:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1198:     MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1199:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1200:   }
1201:   PetscFunctionReturn(viewer);
1202: }