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, ignored if using MPI IO */
 14: #if defined(PETSC_HAVE_MPIIO)
 15:   PetscTruth    MPIIO;
 16:   MPI_File      mfdes;           /* ignored unless using MPI IO */
 17:   MPI_Offset    moff;
 18: #endif
 19:   PetscFileMode btype;           /* read or write? */
 20:   FILE          *fdes_info;      /* optional file containing info on binary file*/
 21:   PetscTruth    storecompressed; /* gzip the write binary file when closing it*/
 22:   char          *filename;
 23:    PetscTruth    skipinfo;        /* Don't create info file for writing; don't use for reading */
 24:   PetscTruth    skipoptions;     /* don't use PETSc options database when loading */
 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:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

201:     Not Collective

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

206:     Output Parameter:
207: .   fdes - file descriptor

209:     Level: advanced

211:     Notes:
212:       For writable binary PetscViewers, the descriptor will only be valid for the 
213:     first processor in the communicator that shares the PetscViewer. For readable 
214:     files it will only be valid on nodes that have the file. If node 0 does not
215:     have the file it generates an error even if another node does have the file.
216:  
217:     Fortran Note:
218:     This routine is not supported in Fortran.

220:   Concepts: file descriptor^getting
221:   Concepts: PetscViewerBinary^accessing file descriptor

223: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
224: @*/
225: PetscErrorCode  PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
226: {
227:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

230:   *fdes = vbinary->fdes;
231:   return(0);
232: }

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

239:     Not Collective

241:     Input Paramter:
242: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

244:     Options Database Key:
245: .   -viewer_binary_skip_info

247:     Level: advanced

249:     Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName()

251:    Concepts: PetscViewerBinary^accessing info file

253: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
254:           PetscViewerBinaryGetSkipOptions()
255: @*/
256: PetscErrorCode  PetscViewerBinarySkipInfo(PetscViewer viewer)
257: {
258:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

261:   vbinary->skipinfo = PETSC_TRUE;
262:   return(0);
263: }

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

270:     Not Collective

272:     Input Parameters:
273: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
274: -   skip - PETSC_TRUE means do not use

276:     Options Database Key:
277: .   -viewer_binary_skip_options

279:     Level: advanced

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

283:    Concepts: PetscViewerBinary^accessing info file

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

293:   vbinary->skipoptions = skip;
294:   return(0);
295: }

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

302:     Not Collective

304:     Input Parameter:
305: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

307:     Output Parameter:
308: .   skip - PETSC_TRUE means do not use

310:     Level: advanced

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

314:    Concepts: PetscViewerBinary^accessing info file

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

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

330: /*@C
331:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
332:           info file associated with a binary file.

334:     Not Collective

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

339:     Output Parameter:
340: .   file - file pointer

342:     Level: advanced

344:     Notes:
345:       For writable binary PetscViewers, the descriptor will only be valid for the 
346:     first processor in the communicator that shares the PetscViewer.
347:  
348:     Fortran Note:
349:     This routine is not supported in Fortran.

351:   Concepts: PetscViewerBinary^accessing info file

353: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
354: @*/
355: PetscErrorCode  PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
356: {
357:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

360:   *file = vbinary->fdes_info;
361:   return(0);
362: }

366: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
367: {
368:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
369:   PetscErrorCode     ierr;
370:   PetscMPIInt        rank;
371:   int                err;

374:   MPI_Comm_rank(((PetscObject)v)->comm,&rank);
375:   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
376:     close(vbinary->fdes);
377:     if (!rank && vbinary->storecompressed) {
378:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
379:       FILE *fp;
380:       /* compress the file */
381:       PetscStrcpy(par,"gzip -f ");
382:       PetscStrcat(par,vbinary->filename);
383: #if defined(PETSC_HAVE_POPEN)
384:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
385:       if (fgets(buf,1024,fp)) {
386:         SETERRQ2(PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
387:       }
388:       PetscPClose(PETSC_COMM_SELF,fp);
389: #else
390:       SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
391: #endif
392:     }
393:   }
394:   if (vbinary->fdes_info) {
395:     err = fclose(vbinary->fdes_info);
396:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
397:   }
398:   PetscStrfree(vbinary->filename);
399:   PetscFree(vbinary);
400:   return(0);
401: }

403: #if defined(PETSC_HAVE_MPIIO)
406: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
407: {
408:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
409:   PetscErrorCode     ierr;
410:   int                err;

413:   if (vbinary->mfdes) {
414:     MPI_File_close(&vbinary->mfdes);
415:   }
416:   if (vbinary->fdes_info) {
417:     err = fclose(vbinary->fdes_info);
418:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
419:   }
420:   PetscStrfree(vbinary->filename);
421:   PetscFree(vbinary);
422:   return(0);
423: }
424: #endif

428: /*@
429:    PetscViewerBinaryCreate - Create a binary viewer.

431:    Collective on MPI_Comm

433:    Input Parameters:
434: .  comm - MPI communicator

436:    Output Parameter:
437: .  binv - PetscViewer for binary input/output

439:    Level: beginner
440: @*/
441: PetscErrorCode  PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer *binv)
442: {
444: 
446:   PetscViewerCreate(comm,binv);
447:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
448:   return(0);
449: }

453: /*@C
454:    PetscViewerBinaryOpen - Opens a file for binary input/output.

456:    Collective on MPI_Comm

458:    Input Parameters:
459: +  comm - MPI communicator
460: .  name - name of file 
461: -  type - type of file
462: $    FILE_MODE_WRITE - create new file for binary output
463: $    FILE_MODE_READ - open existing file for binary input
464: $    FILE_MODE_APPEND - open existing file for binary output

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

469:    Level: beginner

471:    Note:
472:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

480:     For writing files it only opens the file on processor 0 in the communicator.
481:     For readable files it opens the file on all nodes that have the file. If 
482:     node 0 does not have the file it generates an error even if other nodes
483:     do have the file.

485:    Concepts: binary files
486:    Concepts: PetscViewerBinary^creating
487:    Concepts: gzip
488:    Concepts: accessing remote file
489:    Concepts: remote file

491: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
492:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
493:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
494: @*/
495: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
496: {
498: 
500:   PetscViewerCreate(comm,binv);
501:   PetscViewerSetType(*binv,PETSC_VIEWER_BINARY);
502:   PetscViewerFileSetMode(*binv,type);
503:   PetscViewerFileSetName(*binv,name);
504:   return(0);
505: }

507: #if defined(PETSC_HAVE_MPIIO)
510: static PetscErrorCode  PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth write)
511: {
512:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
513:   PetscErrorCode     ierr;
514:   MPI_Datatype       mdtype;
515:   PetscMPIInt        cnt = PetscMPIIntCast(count);
516:   MPI_Status         status;
517:   MPI_Aint           ul,dsize;

520:   PetscDataTypeToMPIDataType(dtype,&mdtype);
521:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
522:   if (write) {
523:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
524:   } else {
525:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
526:   }
527:   MPI_Type_get_extent(mdtype,&ul,&dsize);
528:   vbinary->moff += dsize*cnt;
529:   return(0);
530: }
531: #endif

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

538:    Collective on MPI_Comm

540:    Input Parameters:
541: +  viewer - the binary viewer
542: .  data - location to write the data
543: .  count - number of items of data to read
544: -  datatype - type of data to read

546:    Level: beginner

548:    Concepts: binary files

550: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
551:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
552:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
553: @*/
554: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
555: {
556:   PetscErrorCode     ierr;
557:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

559: #if defined(PETSC_HAVE_MPIIO)
560:   if (vbinary->MPIIO) {
561:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
562:   } else {
563: #endif
564:     PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
565: #if defined(PETSC_HAVE_MPIIO)
566:   }
567: #endif
568:   return(0);
569: }


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

577:    Collective on MPI_Comm

579:    Input Parameters:
580: +  viewer - the binary viewer
581: .  data - location of data
582: .  count - number of items of data to read
583: .  istemp - data may be overwritten
584: -  datatype - type of data to read

586:    Level: beginner

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

590:    Concepts: binary files

592: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
593:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
594:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
595: @*/
596: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscTruth istemp)
597: {
598:   PetscErrorCode     ierr;
599:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

601: #if defined(PETSC_HAVE_MPIIO)
602:   if (vbinary->MPIIO) {
603:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
604:   } else {
605: #endif
606:     PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
607: #if defined(PETSC_HAVE_MPIIO)
608:   }
609: #endif
610:   return(0);
611: }

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

618:    Collective on MPI_Comm

620:    Input Parameters:
621: +  viewer - the binary viewer
622: -  data - location of the array of strings


625:    Level: intermediate

627:    Concepts: binary files

629:     Notes: array of strings is null terminated

631: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
632:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
633:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
634: @*/
635: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
636: {
637:   PetscErrorCode     ierr;
638:   PetscInt           i,n = 0,*sizes;

640:   /* count number of strings */
641:   while (data[n++]);
642:   n--;
643:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
644:   sizes[0] = n;
645:   for (i=0; i<n; i++) {
646:     size_t tmp;
647:     PetscStrlen(data[i],&tmp);
648:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
649:   }
650:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
651:   for (i=0; i<n; i++) {
652:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
653:   }
654:   PetscFree(sizes);
655:   return(0);
656: }

658: /*@C
659:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

661:    Collective on MPI_Comm

663:    Input Parameter:
664: .  viewer - the binary viewer

666:    Output Parameter:
667: .  data - location of the array of strings

669:    Level: intermediate

671:    Concepts: binary files

673:     Notes: array of strings is null terminated

675: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
676:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
677:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
678: @*/
679: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
680: {
681:   PetscErrorCode     ierr;
682:   PetscInt           i,n,*sizes,N = 0;

684:   /* count number of strings */
685:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
686:   PetscMalloc(n*sizeof(PetscInt),&sizes);
687:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
688:   for (i=0; i<n; i++) {
689:     N += sizes[i];
690:   }
691:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
692:   (*data)[0] = (char*)((*data) + n + 1);
693:   for (i=1; i<n; i++) {
694:     (*data)[i] = (*data)[i-1] + sizes[i-1];
695:   }
696:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
697:   (*data)[n] = 0;
698:   PetscFree(sizes);
699:   return(0);
700: }

704: /*@C
705:      PetscViewerFileGetMode - Gets the type of file to be open

707:     Collective on PetscViewer

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

712:   Output Parameter:
713: .  type - type of file
714: $    FILE_MODE_WRITE - create new file for binary output
715: $    FILE_MODE_READ - open existing file for binary input
716: $    FILE_MODE_APPEND - open existing file for binary output

718:   Level: advanced

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

722: @*/
723: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
724: {
725:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode*);

730:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",(void (**)(void))&f);
731:   if (f) {
732:     (*f)(viewer,type);
733:   }
734:   return(0);
735: }

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

743:     Collective on PetscViewer

745:   Input Parameters:
746: .  viewer - the PetscViewer; must be a binary

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

750:   Level: advanced

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

754: @*/
755: PetscErrorCode  PetscViewerBinarySetMPIIO(PetscViewer viewer)
756: {
757:   PetscErrorCode ierr,(*f)(PetscViewer);

761:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerBinarySetMPIIO_C",(void (**)(void))&f);
762:   if (f) {
763:     (*f)(viewer);
764:   }
765:   return(0);
766: }


769: /*@C
770:      PetscViewerFileSetMode - Sets the type of file to be open

772:     Collective on PetscViewer

774:   Input Parameters:
775: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
776: -  type - type of file
777: $    FILE_MODE_WRITE - create new file for binary output
778: $    FILE_MODE_READ - open existing file for binary input
779: $    FILE_MODE_APPEND - open existing file for binary output

781:   Level: advanced

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

785: @*/
786: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
787: {
788:   PetscErrorCode ierr,(*f)(PetscViewer,PetscFileMode);

792:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",(void (**)(void))&f);
793:   if (f) {
794:     (*f)(viewer,type);
795:   }
796:   return(0);
797: }

802: PetscErrorCode  PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
803: {
804:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

807:   *type = vbinary->btype;
808:   return(0);
809: }

815: PetscErrorCode  PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
816: {
817:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

820:   vbinary->btype = type;
821:   return(0);
822: }

825: /*
826:         Actually opens the file 
827: */
831: PetscErrorCode  PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
832: {
833:   PetscMPIInt         rank;
834:   PetscErrorCode      ierr;
835:   size_t              len;
836:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
837:   const char          *fname;
838:   char                bname[PETSC_MAX_PATH_LEN],*gz;
839:   PetscTruth          found;
840:   PetscFileMode       type = vbinary->btype;

843:   if (type == (PetscFileMode) -1) {
844:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
845:   }
846:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
847:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

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

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

854:   /* if ends in .gz strip that off and note user wants file compressed */
855:   vbinary->storecompressed = PETSC_FALSE;
856:   if (!rank && type == FILE_MODE_WRITE) {
857:     /* remove .gz if it ends library name */
858:     PetscStrstr(vbinary->filename,".gz",&gz);
859:     if (gz) {
860:       PetscStrlen(gz,&len);
861:       if (len == 3) {
862:         *gz = 0;
863:         vbinary->storecompressed = PETSC_TRUE;
864:       }
865:     }
866:   }

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

871:     if (type == FILE_MODE_READ){
872:       /* possibly get the file from remote site or compressed file */
873:       PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
874:       fname = bname;
875:       if (!rank && !found) {
876:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
877:       } else if (!found) {
878:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
879:         fname = 0;
880:       }
881:     } else {
882:       fname = vbinary->filename;
883:     }

885: #if defined(PETSC_HAVE_O_BINARY)
886:     if (type == FILE_MODE_WRITE) {
887:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
888:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
889:       }
890:     } else if (type == FILE_MODE_READ && fname) {
891:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
892:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
893:       }
894:     } else if (type == FILE_MODE_APPEND) {
895:       if ((vbinary->fdes = open(fname,O_WRONLY|O_BINARY,0)) == -1) {
896:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
897:       }
898:     } else if (fname) {
899:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
900:     }
901: #else
902:     if (type == FILE_MODE_WRITE) {
903:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
904:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
905:       }
906:     } else if (type == FILE_MODE_READ && fname) {
907:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
908:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
909:       }
910:     } else if (type == FILE_MODE_APPEND) {
911:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
912:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
913:       }
914:     } else if (fname) {
915:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
916:     }
917: #endif
918:   } else vbinary->fdes = -1;
919:   viewer->format = PETSC_VIEWER_NOFORMAT;

921:   /* 
922:       try to open info file: all processors open this file if read only
923:   */
924:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
925:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
926: 
927:     PetscStrcpy(infoname,name);
928:     /* remove .gz if it ends library name */
929:     PetscStrstr(infoname,".gz",&gz);
930:     if (gz) {
931:       PetscStrlen(gz,&len);
932:       if (len == 3) {
933:         *gz = 0;
934:       }
935:     }
936: 
937:     PetscStrcat(infoname,".info");
938:     PetscFixFilename(infoname,iname);
939:     if (type == FILE_MODE_READ) {
940:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
941:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
942:     } else {
943:       vbinary->fdes_info = fopen(infoname,"w");
944:       if (!vbinary->fdes_info) {
945:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
946:       }
947:     }
948:   }

950: #if defined(PETSC_USE_LOG)
951:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
952: #endif
953:   return(0);
954: }

957: #if defined(PETSC_HAVE_MPIIO)
961: PetscErrorCode  PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
962: {
963:   PetscMPIInt         rank;
964:   PetscErrorCode      ierr;
965:   size_t              len;
966:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
967:   char                *gz;
968:   PetscTruth          found;
969:   PetscFileMode       type = vbinary->btype;

972:   if (type == (PetscFileMode) -1) {
973:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
974:   }
975:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
976:   PetscOptionsGetTruth(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

978:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
979:   PetscStrallocpy(name,&vbinary->filename);
980:   vbinary->storecompressed = PETSC_FALSE;


983:   /* only first processor opens file if writeable */
984:   if (type == FILE_MODE_READ) {
985:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
986:   } else if (type == FILE_MODE_WRITE) {
987:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
988:   }
989:   viewer->format = PETSC_VIEWER_NOFORMAT;

991:   /* 
992:       try to open info file: all processors open this file if read only

994:       Below is identical code to the code for Binary above, should be put in seperate routine
995:   */
996:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
997:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
998: 
999:     PetscStrcpy(infoname,name);
1000:     /* remove .gz if it ends library name */
1001:     PetscStrstr(infoname,".gz",&gz);
1002:     if (gz) {
1003:       PetscStrlen(gz,&len);
1004:       if (len == 3) {
1005:         *gz = 0;
1006:       }
1007:     }
1008: 
1009:     PetscStrcat(infoname,".info");
1010:     PetscFixFilename(infoname,iname);
1011:     if (type == FILE_MODE_READ) {
1012:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1013:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1014:     } else {
1015:       vbinary->fdes_info = fopen(infoname,"w");
1016:       if (!vbinary->fdes_info) {
1017:         SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1018:       }
1019:     }
1020:   }

1022: #if defined(PETSC_USE_LOG)
1023:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1024: #endif
1025:   return(0);
1026: }

1032: PetscErrorCode  PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer,PetscFileMode *type)
1033: {
1034:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1035:   PetscErrorCode     ierr;

1038:   if (vbinary->filename) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1039:   viewer->ops->destroy = PetscViewerDestroy_Binary;
1040:   vbinary->MPIIO       = PETSC_TRUE;
1041:   /*  vbinary->skipinfo    = PETSC_TRUE; */
1042:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1043:   return(0);
1044: }
1046: #endif

1051: PetscErrorCode  PetscViewerCreate_Binary(PetscViewer v)
1052: {
1053:   PetscErrorCode     ierr;
1054:   PetscViewer_Binary *vbinary;
1055: #if defined(PETSC_HAVE_MPIIO)
1056:   PetscTruth         useMPIIO = PETSC_FALSE;
1057: #endif

1060:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
1061:   v->data            = (void*)vbinary;
1062:   v->ops->destroy    = PetscViewerDestroy_Binary;
1063:   v->ops->flush      = 0;
1064:   v->iformat         = 0;
1065:   vbinary->fdes_info = 0;
1066:   vbinary->fdes      = 0;
1067:   vbinary->skipinfo        = PETSC_FALSE;
1068:   vbinary->skipoptions     = PETSC_TRUE;
1069:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1070:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1071:   vbinary->btype           = (PetscFileMode) -1;
1072:   vbinary->storecompressed = PETSC_FALSE;
1073:   vbinary->filename        = 0;

1075:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1076:                                     "PetscViewerFileSetName_Binary",
1077:                                      PetscViewerFileSetName_Binary);
1078:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1079:                                     "PetscViewerFileSetMode_Binary",
1080:                                      PetscViewerFileSetMode_Binary);
1081:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1082:                                     "PetscViewerFileGetMode_Binary",
1083:                                      PetscViewerFileGetMode_Binary);
1084: #if defined(PETSC_HAVE_MPIIO)
1085:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1086:                                     "PetscViewerBinarySetMPIIO_Binary",
1087:                                      PetscViewerBinarySetMPIIO_Binary);
1088: 
1089:   PetscOptionsHasName(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO);
1090:   if (useMPIIO) {
1091:     PetscViewerBinarySetMPIIO(v);
1092:   }
1093: #endif
1094:   return(0);
1095: }


1099: /* ---------------------------------------------------------------------*/
1100: /*
1101:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1102:   is attached to a communicator, in this case the attribute is a PetscViewer.
1103: */
1104: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1108: /*@C
1109:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 
1110:                      in a communicator.

1112:      Collective on MPI_Comm

1114:      Input Parameter:
1115: .    comm - the MPI communicator to share the binary PetscViewer
1116:     
1117:      Level: intermediate

1119:    Options Database Keys:
1120: $    -viewer_binary_filename <name>

1122:    Environmental variables:
1123: -   PETSC_VIEWER_BINARY_FILENAME

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

1130: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1131:           PetscViewerDestroy()
1132: @*/
1133: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
1134: {
1136:   PetscTruth     flg;
1137:   PetscViewer    viewer;
1138:   char           fname[PETSC_MAX_PATH_LEN];

1141:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1142:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1143:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1144:   }
1145:   MPI_Attr_get(comm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1146:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1147:   if (!flg) { /* PetscViewer not yet created */
1148:     PetscOptionsGetenv(comm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1149:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1150:     if (!flg) {
1151:       PetscStrcpy(fname,"binaryoutput");
1152:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1153:     }
1154:     PetscViewerBinaryOpen(comm,fname,FILE_MODE_WRITE,&viewer);
1155:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1156:     PetscObjectRegisterDestroy((PetscObject)viewer);
1157:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1158:     MPI_Attr_put(comm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1159:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,1,1," ");return(0);}
1160:   }
1161:   PetscFunctionReturn(viewer);
1162: }