Actual source code: filev.c
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>
4: #define QUEUESTRINGSIZE 8192
6: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
7: {
8: PetscErrorCode ierr;
9: PetscMPIInt rank;
10: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
11: int err;
14: if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
15: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
16: if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
17: if (vascii->fd && vascii->closefile) {
18: err = fclose(vascii->fd);
19: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
20: }
21: if (vascii->storecompressed) {
22: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
23: FILE *fp;
24: PetscStrncpy(par,"gzip ",sizeof(par));
25: PetscStrlcat(par,vascii->filename,sizeof(par));
26: #if defined(PETSC_HAVE_POPEN)
27: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
28: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
29: PetscPClose(PETSC_COMM_SELF,fp);
30: #else
31: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
32: #endif
33: }
34: }
35: PetscFree(vascii->filename);
36: return(0);
37: }
39: /* ----------------------------------------------------------------------*/
40: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
41: {
42: PetscErrorCode ierr;
43: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
44: PetscViewerLink *vlink;
45: PetscBool flg;
48: if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
49: PetscViewerFileClose_ASCII(viewer);
50: PetscFree(vascii);
52: /* remove the viewer from the list in the MPI Communicator */
53: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
54: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
55: }
57: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
58: if (flg) {
59: if (vlink && vlink->viewer == viewer) {
60: if (vlink->next) {
61: MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
62: } else {
63: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
64: }
65: PetscFree(vlink);
66: } else {
67: while (vlink && vlink->next) {
68: if (vlink->next->viewer == viewer) {
69: PetscViewerLink *nv = vlink->next;
70: vlink->next = vlink->next->next;
71: PetscFree(nv);
72: }
73: vlink = vlink->next;
74: }
75: }
76: }
78: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
79: PetscViewer aviewer;
80: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
81: if (flg && aviewer == viewer) {
82: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
83: }
84: }
85: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
86: PetscViewer aviewer;
87: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
88: if (flg && aviewer == viewer) {
89: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
90: }
91: }
92: return(0);
93: }
95: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
96: {
97: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
98: PetscErrorCode ierr;
101: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
102: return(0);
103: }
105: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
106: {
107: PetscErrorCode ierr;
108: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
109: int err;
110: MPI_Comm comm;
111: PetscMPIInt rank,size;
112: FILE *fd = vascii->fd;
115: if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
116: PetscObjectGetComm((PetscObject)viewer,&comm);
117: MPI_Comm_rank(comm,&rank);
118: MPI_Comm_size(comm,&size);
120: if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
121: err = fflush(vascii->fd);
122: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
123: }
125: if (vascii->allowsynchronized) {
126: PetscMPIInt tag,i,j,n = 0,dummy = 0;
127: char *message;
128: MPI_Status status;
130: PetscCommDuplicate(comm,&comm,&tag);
132: /* First processor waits for messages from all other processors */
133: if (rank == 0) {
134: /* flush my own messages that I may have queued up */
135: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
136: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
137: if (!vascii->bviewer) {
138: PetscFPrintf(comm,fd,"%s",next->string);
139: } else {
140: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
141: }
142: previous = next;
143: next = next->next;
144: PetscFree(previous->string);
145: PetscFree(previous);
146: }
147: vascii->petsc_printfqueue = NULL;
148: vascii->petsc_printfqueuelength = 0;
149: for (i=1; i<size; i++) {
150: /* to prevent a flood of messages to process zero, request each message separately */
151: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
152: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
153: for (j=0; j<n; j++) {
154: PetscMPIInt size = 0;
156: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
157: PetscMalloc1(size, &message);
158: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
159: if (!vascii->bviewer) {
160: PetscFPrintf(comm,fd,"%s",message);
161: } else {
162: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
163: }
164: PetscFree(message);
165: }
166: }
167: } else { /* other processors send queue to processor 0 */
168: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
170: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
171: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
172: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
173: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
174: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
175: previous = next;
176: next = next->next;
177: PetscFree(previous->string);
178: PetscFree(previous);
179: }
180: vascii->petsc_printfqueue = NULL;
181: vascii->petsc_printfqueuelength = 0;
182: }
183: PetscCommDestroy(&comm);
184: }
185: return(0);
186: }
188: /*@C
189: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
191: Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
193: Input Parameter:
194: . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
196: Output Parameter:
197: . fd - file pointer
199: Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
201: Level: intermediate
203: Fortran Note:
204: This routine is not supported in Fortran.
206: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
207: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
208: @*/
209: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
210: {
211: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
214: *fd = vascii->fd;
215: return(0);
216: }
218: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
219: {
220: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
223: *mode = vascii->mode;
224: return(0);
225: }
227: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
228: {
229: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
232: vascii->mode = mode;
233: return(0);
234: }
236: /*
237: If petsc_history is on, then all Petsc*Printf() results are saved
238: if the appropriate (usually .petschistory) file.
239: */
240: PETSC_INTERN FILE *petsc_history;
242: /*@
243: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
245: Not Collective, but only first processor in set has any effect
247: Input Parameters:
248: + viewer - obtained with PetscViewerASCIIOpen()
249: - tabs - number of tabs
251: Level: developer
253: Fortran Note:
254: This routine is not supported in Fortran.
256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
257: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259: @*/
260: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
261: {
262: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
263: PetscBool iascii;
264: PetscErrorCode ierr;
268: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
269: if (iascii) ascii->tab = tabs;
270: return(0);
271: }
273: /*@
274: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
276: Not Collective, meaningful on first processor only.
278: Input Parameters:
279: . viewer - obtained with PetscViewerASCIIOpen()
281: Output Parameters:
282: . tabs - number of tabs
284: Level: developer
286: Fortran Note:
287: This routine is not supported in Fortran.
289: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
290: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
291: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
292: @*/
293: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
294: {
295: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
296: PetscBool iascii;
297: PetscErrorCode ierr;
301: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
302: if (iascii && tabs) *tabs = ascii->tab;
303: return(0);
304: }
306: /*@
307: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
309: Not Collective, but only first processor in set has any effect
311: Input Parameters:
312: + viewer - obtained with PetscViewerASCIIOpen()
313: - tabs - number of tabs
315: Level: developer
317: Fortran Note:
318: This routine is not supported in Fortran.
320: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
321: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
322: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
323: @*/
324: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
325: {
326: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
327: PetscBool iascii;
328: PetscErrorCode ierr;
332: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
333: if (iascii) ascii->tab += tabs;
334: return(0);
335: }
337: /*@
338: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
340: Not Collective, but only first processor in set has any effect
342: Input Parameters:
343: + viewer - obtained with PetscViewerASCIIOpen()
344: - tabs - number of tabs
346: Level: developer
348: Fortran Note:
349: This routine is not supported in Fortran.
351: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
352: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
353: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
354: @*/
355: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
356: {
357: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
358: PetscBool iascii;
359: PetscErrorCode ierr;
363: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
364: if (iascii) ascii->tab -= tabs;
365: return(0);
366: }
368: /*@C
369: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
371: Collective on PetscViewer
373: Input Parameters:
374: . viewer - obtained with PetscViewerASCIIOpen()
376: Level: intermediate
378: Notes:
379: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
381: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
382: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
383: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
384: @*/
385: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
386: {
387: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
388: PetscBool iascii;
389: PetscErrorCode ierr;
393: if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
394: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
395: if (iascii) ascii->allowsynchronized++;
396: return(0);
397: }
399: /*@C
400: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
402: Collective on PetscViewer
404: Input Parameters:
405: . viewer - obtained with PetscViewerASCIIOpen()
407: Level: intermediate
409: Notes:
410: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
412: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
413: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
414: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
415: @*/
416: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
417: {
418: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
419: PetscBool iascii;
420: PetscErrorCode ierr;
424: if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
425: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
426: if (iascii) {
427: ascii->allowsynchronized--;
428: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
429: }
430: return(0);
431: }
433: /*@C
434: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
435: lines are tabbed.
437: Not Collective, but only first processor in set has any effect
439: Input Parameters:
440: . viewer - obtained with PetscViewerASCIIOpen()
442: Level: developer
444: Fortran Note:
445: This routine is not supported in Fortran.
447: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
448: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
449: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
450: @*/
451: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
452: {
453: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
454: PetscBool iascii;
455: PetscErrorCode ierr;
459: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
460: if (iascii) ascii->tab++;
461: return(0);
462: }
464: /*@C
465: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
466: lines are tabbed.
468: Not Collective, but only first processor in set has any effect
470: Input Parameters:
471: . viewer - obtained with PetscViewerASCIIOpen()
473: Level: developer
475: Fortran Note:
476: This routine is not supported in Fortran.
478: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
479: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
480: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
481: @*/
482: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
483: {
484: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
485: PetscErrorCode ierr;
486: PetscBool iascii;
490: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
491: if (iascii) {
492: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
493: ascii->tab--;
494: }
495: return(0);
496: }
498: /*@
499: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
501: Not Collective, but only first processor in set has any effect
503: Input Parameters:
504: + viewer - obtained with PetscViewerASCIIOpen()
505: - flg - PETSC_TRUE or PETSC_FALSE
507: Level: developer
509: Fortran Note:
510: This routine is not supported in Fortran.
512: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
513: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
514: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
515: @*/
516: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
517: {
518: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
519: PetscBool iascii;
520: PetscErrorCode ierr;
524: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
525: if (iascii) {
526: if (flg) ascii->tab = ascii->tab_store;
527: else {
528: ascii->tab_store = ascii->tab;
529: ascii->tab = 0;
530: }
531: }
532: return(0);
533: }
535: /* ----------------------------------------------------------------------- */
537: /*@C
538: PetscViewerASCIIPrintf - Prints to a file, only from the first
539: processor in the PetscViewer
541: Not Collective, but only first processor in set has any effect
543: Input Parameters:
544: + viewer - obtained with PetscViewerASCIIOpen()
545: - format - the usual printf() format string
547: Level: developer
549: Fortran Note:
550: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
551: That is, you can only pass a single character string from Fortran.
553: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
554: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
555: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
556: @*/
557: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
558: {
559: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
560: PetscMPIInt rank;
561: PetscInt tab,intab = ascii->tab;
562: PetscErrorCode ierr;
563: FILE *fd = ascii->fd;
564: PetscBool iascii;
565: int err;
569: if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
571: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
572: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
573: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
574: if (rank) return(0);
576: if (ascii->bviewer) { /* pass string up to parent viewer */
577: char *string;
578: va_list Argp;
579: size_t fullLength;
581: PetscCalloc1(QUEUESTRINGSIZE, &string);
582: va_start(Argp,format);
583: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
584: va_end(Argp);
585: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
586: PetscFree(string);
587: } else { /* write directly to file */
588: va_list Argp;
589: /* flush my own messages that I may have queued up */
590: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
591: PetscInt i;
592: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
593: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
594: previous = next;
595: next = next->next;
596: PetscFree(previous->string);
597: PetscFree(previous);
598: }
599: ascii->petsc_printfqueue = NULL;
600: ascii->petsc_printfqueuelength = 0;
601: tab = intab;
602: while (tab--) {
603: PetscFPrintf(PETSC_COMM_SELF,fd," ");
604: }
606: va_start(Argp,format);
607: (*PetscVFPrintf)(fd,format,Argp);
608: err = fflush(fd);
609: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
610: if (petsc_history) {
611: va_start(Argp,format);
612: tab = intab;
613: while (tab--) {
614: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
615: }
616: (*PetscVFPrintf)(petsc_history,format,Argp);
617: err = fflush(petsc_history);
618: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
619: }
620: va_end(Argp);
621: }
622: return(0);
623: }
625: /*@C
626: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
628: Collective on PetscViewer
630: Input Parameters:
631: + viewer - the PetscViewer; either ASCII or binary
632: - name - the name of the file it should use
634: Level: advanced
636: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
637: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
639: @*/
640: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
641: {
643: char filename[PETSC_MAX_PATH_LEN];
648: PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
649: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
650: return(0);
651: }
653: /*@C
654: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
656: Not Collective
658: Input Parameter:
659: . viewer - the PetscViewer; either ASCII or binary
661: Output Parameter:
662: . name - the name of the file it is using
664: Level: advanced
666: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
668: @*/
669: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
670: {
676: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
677: return(0);
678: }
680: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
681: {
682: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
685: *name = vascii->filename;
686: return(0);
687: }
689: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
690: {
691: PetscErrorCode ierr;
692: size_t len;
693: char fname[PETSC_MAX_PATH_LEN],*gz;
694: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
695: PetscBool isstderr,isstdout;
696: PetscMPIInt rank;
699: PetscViewerFileClose_ASCII(viewer);
700: if (!name) return(0);
701: PetscStrallocpy(name,&vascii->filename);
703: /* Is this file to be compressed */
704: vascii->storecompressed = PETSC_FALSE;
706: PetscStrstr(vascii->filename,".gz",&gz);
707: if (gz) {
708: PetscStrlen(gz,&len);
709: if (len == 3) {
710: if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
711: *gz = 0;
712: vascii->storecompressed = PETSC_TRUE;
713: }
714: }
715: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
716: if (rank == 0) {
717: PetscStrcmp(name,"stderr",&isstderr);
718: PetscStrcmp(name,"stdout",&isstdout);
719: /* empty filename means stdout */
720: if (name[0] == 0) isstdout = PETSC_TRUE;
721: if (isstderr) vascii->fd = PETSC_STDERR;
722: else if (isstdout) vascii->fd = PETSC_STDOUT;
723: else {
725: PetscFixFilename(name,fname);
726: switch (vascii->mode) {
727: case FILE_MODE_READ:
728: vascii->fd = fopen(fname,"r");
729: break;
730: case FILE_MODE_WRITE:
731: vascii->fd = fopen(fname,"w");
732: break;
733: case FILE_MODE_APPEND:
734: vascii->fd = fopen(fname,"a");
735: break;
736: case FILE_MODE_UPDATE:
737: vascii->fd = fopen(fname,"r+");
738: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
739: break;
740: case FILE_MODE_APPEND_UPDATE:
741: /* I really want a file which is opened at the end for updating,
742: not a+, which opens at the beginning, but makes writes at the end.
743: */
744: vascii->fd = fopen(fname,"r+");
745: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
746: else {
747: fseek(vascii->fd, 0, SEEK_END);
748: }
749: break;
750: default:
751: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
752: }
753: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
754: }
755: }
756: #if defined(PETSC_USE_LOG)
757: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
758: #endif
759: return(0);
760: }
762: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
763: {
764: PetscErrorCode ierr;
765: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
768: PetscViewerASCIIPushSynchronized(viewer);
769: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
770: /*
771: The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
772: because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
773: (since the count never gets to zero) in some examples this displays information that otherwise would be lost
775: This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
776: PCView_GASM().
777: */
778: PetscViewerASCIIPushSynchronized(viewer);
779: PetscViewerCreate(subcomm,outviewer);
780: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
781: PetscViewerASCIIPushSynchronized(*outviewer);
782: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
783: ovascii->fd = vascii->fd;
784: ovascii->tab = vascii->tab;
785: ovascii->closefile = PETSC_FALSE;
787: vascii->sviewer = *outviewer;
788: (*outviewer)->format = viewer->format;
789: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
790: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
791: return(0);
792: }
794: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
795: {
796: PetscErrorCode ierr;
797: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
800: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
801: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
803: PetscViewerASCIIPopSynchronized(*outviewer);
804: ascii->sviewer = NULL;
805: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
806: PetscViewerDestroy(outviewer);
807: PetscViewerASCIIPopSynchronized(viewer);
808: return(0);
809: }
811: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
812: {
813: PetscErrorCode ierr;
814: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
817: if (ascii->filename) {
818: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
819: }
820: return(0);
821: }
823: /*MC
824: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
826: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
827: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
828: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
830: Level: beginner
832: M*/
833: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
834: {
835: PetscViewer_ASCII *vascii;
836: PetscErrorCode ierr;
839: PetscNewLog(viewer,&vascii);
840: viewer->data = (void*)vascii;
842: viewer->ops->destroy = PetscViewerDestroy_ASCII;
843: viewer->ops->flush = PetscViewerFlush_ASCII;
844: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
845: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
846: viewer->ops->view = PetscViewerView_ASCII;
847: viewer->ops->read = PetscViewerASCIIRead;
849: /* defaults to stdout unless set with PetscViewerFileSetName() */
850: vascii->fd = PETSC_STDOUT;
851: vascii->mode = FILE_MODE_WRITE;
852: vascii->bviewer = NULL;
853: vascii->subviewer = NULL;
854: vascii->sviewer = NULL;
855: vascii->tab = 0;
856: vascii->tab_store = 0;
857: vascii->filename = NULL;
858: vascii->closefile = PETSC_TRUE;
860: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
861: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
862: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
863: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
864: return(0);
865: }
867: /*@C
868: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
869: several processors. Output of the first processor is followed by that of the
870: second, etc.
872: Not Collective, must call collective PetscViewerFlush() to get the results out
874: Input Parameters:
875: + viewer - the ASCII PetscViewer
876: - format - the usual printf() format string
878: Level: intermediate
880: Notes:
881: You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
882: Then you can do multiple independent calls to this routine.
883: The actual synchronized print is then done using PetscViewerFlush().
884: PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
885: to conclude the "synchronized session".
886: So the typical calling sequence looks like
887: $ PetscViewerASCIIPushSynchronized(viewer);
888: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
889: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
890: $ ...
891: $ PetscViewerFlush(viewer);
892: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
893: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
894: $ ...
895: $ PetscViewerFlush(viewer);
896: $ PetscViewerASCIIPopSynchronized(viewer);
898: Fortran Note:
899: Can only print a single character* string
901: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
902: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
903: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
904: @*/
905: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
906: {
907: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
908: PetscErrorCode ierr;
909: PetscMPIInt rank;
910: PetscInt tab = vascii->tab;
911: MPI_Comm comm;
912: FILE *fp;
913: PetscBool iascii,hasbviewer = PETSC_FALSE;
914: int err;
919: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
920: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
921: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
923: PetscObjectGetComm((PetscObject)viewer,&comm);
924: MPI_Comm_rank(comm,&rank);
926: if (vascii->bviewer) {
927: hasbviewer = PETSC_TRUE;
928: if (rank == 0) {
929: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
930: PetscObjectGetComm((PetscObject)viewer,&comm);
931: MPI_Comm_rank(comm,&rank);
932: }
933: }
935: fp = vascii->fd;
937: if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
938: va_list Argp;
939: /* flush my own messages that I may have queued up */
940: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
941: PetscInt i;
942: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
943: PetscFPrintf(comm,fp,"%s",next->string);
944: previous = next;
945: next = next->next;
946: PetscFree(previous->string);
947: PetscFree(previous);
948: }
949: vascii->petsc_printfqueue = NULL;
950: vascii->petsc_printfqueuelength = 0;
952: while (tab--) {
953: PetscFPrintf(PETSC_COMM_SELF,fp," ");
954: }
956: va_start(Argp,format);
957: (*PetscVFPrintf)(fp,format,Argp);
958: err = fflush(fp);
959: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
960: if (petsc_history) {
961: va_start(Argp,format);
962: (*PetscVFPrintf)(petsc_history,format,Argp);
963: err = fflush(petsc_history);
964: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
965: }
966: va_end(Argp);
967: } else { /* other processors add to queue */
968: char *string;
969: va_list Argp;
970: size_t fullLength;
971: PrintfQueue next;
973: PetscNew(&next);
974: if (vascii->petsc_printfqueue) {
975: vascii->petsc_printfqueue->next = next;
976: vascii->petsc_printfqueue = next;
977: } else {
978: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
979: }
980: vascii->petsc_printfqueuelength++;
981: next->size = QUEUESTRINGSIZE;
982: PetscCalloc1(next->size, &next->string);
983: string = next->string;
984: tab *= 2;
985: while (tab--) {
986: *string++ = ' ';
987: }
988: va_start(Argp,format);
989: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
990: va_end(Argp);
991: if (fullLength > (size_t) (next->size-2*vascii->tab)) {
992: PetscFree(next->string);
993: next->size = fullLength + 2*vascii->tab;
994: PetscCalloc1(next->size, &next->string);
995: string = next->string;
996: tab = 2*vascii->tab;
997: while (tab--) {
998: *string++ = ' ';
999: }
1000: va_start(Argp,format);
1001: PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1002: va_end(Argp);
1003: }
1004: }
1005: return(0);
1006: }
1008: /*@C
1009: PetscViewerASCIIRead - Reads from a ASCII file
1011: Only process 0 in the PetscViewer may call this
1013: Input Parameters:
1014: + viewer - the ascii viewer
1015: . data - location to write the data
1016: . num - number of items of data to read
1017: - datatype - type of data to read
1019: Output Parameters:
1020: . count - number of items of data actually read, or NULL
1022: Level: beginner
1024: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1025: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1026: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1027: @*/
1028: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1029: {
1030: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1031: FILE *fd = vascii->fd;
1032: PetscInt i;
1033: int ret = 0;
1034: PetscMPIInt rank;
1035: PetscErrorCode ierr;
1039: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1040: if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1041: for (i=0; i<num; i++) {
1042: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1043: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1044: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1045: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1046: else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i]));
1047: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1048: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1049: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1050: #if defined(PETSC_USE_REAL___FLOAT128)
1051: else if (dtype == PETSC___FLOAT128) {
1052: double tmp;
1053: ret = fscanf(fd, "%lg", &tmp);
1054: ((__float128*)data)[i] = tmp;
1055: }
1056: #endif
1057: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1058: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1059: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1060: }
1061: if (count) *count = i;
1062: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1063: return(0);
1064: }