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: }