Actual source code: filev.c

  1: /* $Id: filev.c,v 1.118 2001/04/10 19:34:05 bsmith Exp $ */

  3: #include "src/sys/src/viewer/viewerimpl.h"  /*I     "petsc.h"   I*/
  4: #include "petscfix.h"
  5: #include <stdarg.h>

  7: typedef struct {
  8:   FILE          *fd;
  9:   int           tab;            /* how many times text is tabbed in from left */
 10:   int           tab_store;      /* store tabs value while tabs are turned off */
 11:   PetscViewer   bviewer;        /* if PetscViewer is a singleton, this points to mother */
 12:   PetscViewer   sviewer;        /* if PetscViewer has a singleton, this points to singleton */
 13:   char          *filename;
 14:   PetscTruth    storecompressed;
 15: } PetscViewer_ASCII;

 17: /* ----------------------------------------------------------------------*/
 18: int PetscViewerDestroy_ASCII(PetscViewer viewer)
 19: {
 20:   int               rank,ierr;
 21:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 24:   if (vascii->sviewer) {
 25:     SETERRQ(1,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
 26:   }
 27:   MPI_Comm_rank(viewer->comm,&rank);
 28:   if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
 29:     fclose(vascii->fd);
 30:     if (vascii->storecompressed) {
 31:       char par[1024],buf[1024];
 32:       FILE *fp;
 33:       PetscStrcpy(par,"gzip ");
 34:       PetscStrcat(par,vascii->filename);
 35:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
 36:       if (fgets(buf,1024,fp)) {
 37:         SETERRQ2(1,"Error from compression command %s %sn%s",par,buf);
 38:       }
 39:     }
 40:   }
 41:   PetscStrfree(vascii->filename);
 42:   PetscFree(vascii);
 43:   return(0);
 44: }

 46: int PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 47: {
 48:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 49:   int               ierr;
 51:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 52:   return(0);
 53: }

 55: int PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 56: {
 57:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 60:   fflush(vascii->fd);
 61:   return(0);
 62: }

 64: int PetscViewerFlush_ASCII(PetscViewer viewer)
 65: {
 66:   int               rank,ierr;
 67:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 70:   MPI_Comm_rank(viewer->comm,&rank);
 71:   if (!rank) {
 72:     fflush(vascii->fd);
 73:   }

 75:   /*
 76:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
 77:   */
 78:   PetscSynchronizedFlush(viewer->comm);
 79:   return(0);
 80: }

 82: /*@C
 83:     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.

 85:     Not Collective

 87: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
 88: -   fd - file pointer

 90:     Level: intermediate

 92:     Fortran Note:
 93:     This routine is not supported in Fortran.

 95:   Concepts: PetscViewer^file pointer
 96:   Concepts: file pointer^getting from PetscViewer

 98: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
 99:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
100: @*/
101: int PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
102: {
103:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

106:   *fd = vascii->fd;
107:   return(0);
108: }

110: /*
111:    If petsc_history is on, then all Petsc*Printf() results are saved
112:    if the appropriate (usually .petschistory) file.
113: */
114: extern FILE *petsc_history;

116: /*@C
117:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

119:     Not Collective, but only first processor in set has any effect

121:     Input Parameters:
122: +    viewer - optained with PetscViewerASCIIOpen()
123: -    tabs - number of tabs

125:     Level: developer

127:     Fortran Note:
128:     This routine is not supported in Fortran.

130:   Concepts: PetscViewerASCII^formating
131:   Concepts: tab^setting

133: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
134:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
135:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
136: @*/
137: int PetscViewerASCIISetTab(PetscViewer viewer,int tabs)
138: {
139:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
140:   PetscTruth        isascii;
141:   int               ierr;

145:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
146:   if (isascii) {
147:     ascii->tab = tabs;
148:   }
149:   return(0);
150: }

152: /*@C
153:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
154:      lines are tabbed.

156:     Not Collective, but only first processor in set has any effect

158:     Input Parameters:
159: .    viewer - optained with PetscViewerASCIIOpen()

161:     Level: developer

163:     Fortran Note:
164:     This routine is not supported in Fortran.

166:   Concepts: PetscViewerASCII^formating
167:   Concepts: tab^setting

169: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
170:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
171:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
172: @*/
173: int PetscViewerASCIIPushTab(PetscViewer viewer)
174: {
175:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
176:   PetscTruth        isascii;
177:   int               ierr;

181:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
182:   if (isascii) {
183:     ascii->tab++;
184:   }
185:   return(0);
186: }

188: /*@C
189:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
190:      lines are tabbed.

192:     Not Collective, but only first processor in set has any effect

194:     Input Parameters:
195: .    viewer - optained with PetscViewerASCIIOpen()

197:     Level: developer

199:     Fortran Note:
200:     This routine is not supported in Fortran.

202:   Concepts: PetscViewerASCII^formating
203:   Concepts: tab^setting

205: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
206:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
207:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
208: @*/
209: int PetscViewerASCIIPopTab(PetscViewer viewer)
210: {
211:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
212:   int               ierr;
213:   PetscTruth        isascii;

217:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
218:   if (isascii) {
219:     if (ascii->tab <= 0) SETERRQ(1,"More tabs popped than pushed");
220:     ascii->tab--;
221:   }
222:   return(0);
223: }

225: /*@C
226:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

228:     Not Collective, but only first processor in set has any effect

230:     Input Parameters:
231: +    viewer - optained with PetscViewerASCIIOpen()
232: -    flg - PETSC_YES or PETSC_NO

234:     Level: developer

236:     Fortran Note:
237:     This routine is not supported in Fortran.

239:   Concepts: PetscViewerASCII^formating
240:   Concepts: tab^setting

242: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
243:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
244:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
245: @*/
246: int PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
247: {
248:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
249:   PetscTruth        isascii;
250:   int               ierr;

254:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
255:   if (isascii) {
256:     if (flg) {
257:       ascii->tab       = ascii->tab_store;
258:     } else {
259:       ascii->tab_store = ascii->tab;
260:       ascii->tab       = 0;
261:     }
262:   }
263:   return(0);
264: }

266: /* ----------------------------------------------------------------------- */

268: #include "src/sys/src/fileio/mprint.h" /* defines the queue datastructures and variables */

270: /*@C
271:     PetscViewerASCIIPrintf - Prints to a file, only from the first
272:     processor in the PetscViewer

274:     Not Collective, but only first processor in set has any effect

276:     Input Parameters:
277: +    viewer - optained with PetscViewerASCIIOpen()
278: -    format - the usual printf() format string 

280:     Level: developer

282:     Fortran Note:
283:     This routine is not supported in Fortran.

285:   Concepts: PetscViewerASCII^printing
286:   Concepts: printing^to file
287:   Concepts: printf

289: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
290:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
291:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
292: @*/
293: int PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
294: {
295:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
296:   int               rank,tab,ierr;
297:   FILE              *fd = ascii->fd;
298:   PetscTruth        isascii;

302:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
303:   if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");

305:   MPI_Comm_rank(viewer->comm,&rank);
306:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
307:   if (!rank) {
308:     va_list Argp;
309:     if (ascii->bviewer) {
310:       queuefile = fd;
311:     }

313:     tab = ascii->tab;
314:     while (tab--) fprintf(fd,"  ");

316:     va_start(Argp,format);
317: #if defined(PETSC_HAVE_VPRINTF_CHAR)
318:     vfprintf(fd,format,(char*)Argp);
319: #else
320:     vfprintf(fd,format,Argp);
321: #endif
322:     fflush(fd);
323:     if (petsc_history) {
324:       tab = ascii->tab;
325:       while (tab--) fprintf(fd,"  ");
326: #if defined(PETSC_HAVE_VPRINTF_CHAR)
327:       vfprintf(petsc_history,format,(char *)Argp);
328: #else
329:       vfprintf(petsc_history,format,Argp);
330: #endif
331:       fflush(petsc_history);
332:     }
333:     va_end(Argp);
334:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
335:     int         len;
336:     va_list     Argp;

338:     PrintfQueue next;
339:     PetscNew(struct _PrintfQueue,&next);
340:     if (queue) {queue->next = next; queue = next;}
341:     else       {queuebase   = queue = next;}
342:     queuelength++;
343:     va_start(Argp,format);
344: #if defined(PETSC_HAVE_VPRINTF_CHAR)
345:     vsprintf(next->string,format,(char *)Argp);
346: #else
347:     vsprintf(next->string,format,Argp);
348: #endif
349:     va_end(Argp);
350:     PetscStrlen(next->string,&len);
351:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
352:   }
353:   return(0);
354: }

356: /*@C
357:      PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.

359:     Collective on PetscViewer

361:   Input Parameters:
362: +  viewer - the PetscViewer; either ASCII or binary
363: -  name - the name of the file it should use

365:     Level: advanced

367: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
368:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

370: @*/
371: int PetscViewerSetFilename(PetscViewer viewer,const char name[])
372: {
373:   int ierr,(*f)(PetscViewer,const char[]);

377:   if (!name) SETERRQ(1,"You must pass in non-null string");
378:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)())&f);
379:   if (f) {
380:     (*f)(viewer,name);
381:   }

383:   return(0);
384: }

386: /*@C
387:      PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.

389:     Not Collective

391:   Input Parameter:
392: .  viewer - the PetscViewer; either ASCII or binary

394:   Output Parameter:
395: .  name - the name of the file it is using

397:     Level: advanced

399: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerSetFilename()

401: @*/
402: int PetscViewerGetFilename(PetscViewer viewer,char **name)
403: {
404:   int ierr,(*f)(PetscViewer,char **);

408:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)())&f);
409:   if (f) {
410:     (*f)(viewer,name);
411:   }

413:   return(0);
414: }

416: EXTERN_C_BEGIN
417: int PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
418: {
419:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

422:   *name = vascii->filename;
423:   return(0);
424: }
425: EXTERN_C_END

427: EXTERN_C_BEGIN
428: int PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
429: {
430:   int               ierr,len;
431:   char              fname[256],*gz;
432:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
433:   PetscTruth        isstderr,isstdout;

436:   if (!name) return(0);

438:   PetscStrallocpy(name,&vascii->filename);

440:   /* Is this file to be compressed */
441:   vascii->storecompressed = PETSC_FALSE;
442:   PetscStrstr(vascii->filename,".gz",&gz);
443:   if (gz) {
444:     PetscStrlen(gz,&len);
445:     if (len == 3) {
446:       *gz = 0;
447:       vascii->storecompressed = PETSC_TRUE;
448:     }
449:   }
450:   PetscStrcmp(name,"stderr",&isstderr);
451:   PetscStrcmp(name,"stdout",&isstdout);
452:   if (isstderr)      vascii->fd = stderr;
453:   else if (isstdout) vascii->fd = stdout;
454:   else {
455:     ierr         = PetscFixFilename(name,fname);
456:     vascii->fd   = fopen(fname,"w");
457:     if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
458:   }
459: #if defined(PETSC_USE_LOG)
460:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
461: #endif

463:   return(0);
464: }
465: EXTERN_C_END

467: int PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
468: {
469:   int               rank,ierr;
470:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
471:   char              *name;

474:   if (vascii->sviewer) {
475:     SETERRQ(1,"Singleton already obtained from PetscViewer and not restored");
476:   }
477:   ierr         = PetscViewerCreate(PETSC_COMM_SELF,outviewer);
478:   ierr         = PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
479:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
480:   ovascii->fd  = vascii->fd;
481:   ovascii->tab = vascii->tab;

483:   vascii->sviewer = *outviewer;

485:   (*outviewer)->format     = viewer->format;
486:   (*outviewer)->iformat    = viewer->iformat;

488:   PetscObjectGetName((PetscObject)viewer,&name);
489:   PetscObjectSetName((PetscObject)(*outviewer),name);

491:   MPI_Comm_rank(viewer->comm,&rank);
492:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
493:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
494:   if (rank) {
495:     (*outviewer)->ops->flush = 0;
496:   } else {
497:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
498:   }
499:   return(0);
500: }

502: int PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
503: {
504:   int               ierr;
505:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
506:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

509:   if (!ascii->sviewer) {
510:     SETERRQ(1,"Singleton never obtained from PetscViewer");
511:   }
512:   if (ascii->sviewer != *outviewer) {
513:     SETERRQ(1,"This PetscViewer did not generate singleton");
514:   }

516:   ascii->sviewer             = 0;
517:   vascii->fd                 = stdout;
518:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
519:   ierr                       = PetscViewerDestroy(*outviewer);
520:   PetscViewerFlush(viewer);
521:   return(0);
522: }

524: EXTERN_C_BEGIN
525: int PetscViewerCreate_ASCII(PetscViewer viewer)
526: {
527:   PetscViewer_ASCII *vascii;
528:   int               ierr;

531:   ierr         = PetscNew(PetscViewer_ASCII,&vascii);
532:   viewer->data = (void*)vascii;

534:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
535:   viewer->ops->flush            = PetscViewerFlush_ASCII;
536:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
537:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

539:   /* defaults to stdout unless set with PetscViewerSetFilename() */
540:   vascii->fd             = stdout;
541:   vascii->bviewer        = 0;
542:   vascii->sviewer        = 0;
543:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
544:   viewer->iformat        = 0;
545:   vascii->tab            = 0;
546:   vascii->tab_store      = 0;
547:   vascii->filename       = 0;

549:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
550:                                      PetscViewerSetFilename_ASCII);
551:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
552:                                      PetscViewerGetFilename_ASCII);

554:   return(0);
555: }
556: EXTERN_C_END


559: /*@C
560:     PetscViewerASCIISynchronizedFPrintf - Prints synchronized output to the specified file from
561:     several processors.  Output of the first processor is followed by that of the 
562:     second, etc.

564:     Not Collective, must call collective PetscViewerFlush() to get the results out

566:     Input Parameters:
567: +   viewer - the ASCII PetscViewer
568: -   format - the usual printf() format string 

570:     Level: intermediate

572: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
573:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
574:           PetscViewerASCIIPrintf()

576: @*/
577: int PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
578: {
579:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
580:   int               ierr,rank,tab = vascii->tab;
581:   MPI_Comm          comm;
582:   FILE              *fp;
583:   PetscTruth        isascii;

587:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
588:   if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");

590:   comm = viewer->comm;
591:   fp   = vascii->fd;
592:   MPI_Comm_rank(comm,&rank);
593:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
594: 

596:   /* First processor prints immediately to fp */
597:   if (!rank) {
598:     va_list Argp;

600:     while (tab--) fprintf(fp,"  ");

602:     va_start(Argp,format);
603: #if defined(PETSC_HAVE_VPRINTF_CHAR)
604:     vfprintf(fp,format,(char*)Argp);
605: #else
606:     vfprintf(fp,format,Argp);
607: #endif
608:     fflush(fp);
609:     queuefile = fp;
610:     if (petsc_history) {
611: #if defined(PETSC_HAVE_VPRINTF_CHAR)
612:       vfprintf(petsc_history,format,(char *)Argp);
613: #else
614:       vfprintf(petsc_history,format,Argp);
615: #endif
616:       fflush(petsc_history);
617:     }
618:     va_end(Argp);
619:   } else { /* other processors add to local queue */
620:     int         len;
621:     char        *string;
622:     va_list     Argp;
623:     PrintfQueue next;

625:     PetscNew(struct _PrintfQueue,&next);
626:     if (queue) {queue->next = next; queue = next;}
627:     else       {queuebase   = queue = next;}
628:     queuelength++;
629:     string = next->string;
630:     while (tab--) {*string++ = ' ';}
631:     va_start(Argp,format);
632: #if defined(PETSC_HAVE_VPRINTF_CHAR)
633:     vsprintf(string,format,(char *)Argp);
634: #else
635:     vsprintf(string,format,Argp);
636: #endif
637:     va_end(Argp);
638:     PetscStrlen(next->string,&len);
639:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
640:   }
641:   return(0);
642: }