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;

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

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

654:    Collective on MPI_Comm

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


661:    Level: intermediate

663:    Concepts: binary files

665:     Notes: array of strings is null terminated

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

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

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

697:    Collective on MPI_Comm

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

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

705:    Level: intermediate

707:    Concepts: binary files

709:     Notes: array of strings is null terminated

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

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

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

743:     Collective on PetscViewer

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

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

754:   Level: advanced

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

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

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

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

779:     Collective on PetscViewer

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

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

786:   Level: advanced

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

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

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


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

808:     Collective on PetscViewer

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

817:   Level: advanced

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

1149:      Collective on MPI_Comm

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

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

1161:    Environmental variables:
1162: -   PETSC_VIEWER_BINARY_FILENAME

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

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

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