Actual source code: filev.c
petsc-3.11.4 2019-09-28
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: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
15: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
16: if (vascii->fd && vascii->closefile) {
17: err = fclose(vascii->fd);
18: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
19: }
20: if (vascii->storecompressed) {
21: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
22: FILE *fp;
23: PetscStrncpy(par,"gzip ",sizeof(par));
24: PetscStrlcat(par,vascii->filename,sizeof(par));
25: #if defined(PETSC_HAVE_POPEN)
26: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
27: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
28: PetscPClose(PETSC_COMM_SELF,fp);
29: #else
30: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
31: #endif
32: }
33: }
34: PetscFree(vascii->filename);
35: return(0);
36: }
38: /* ----------------------------------------------------------------------*/
39: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
40: {
41: PetscErrorCode ierr;
42: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
43: PetscViewerLink *vlink;
44: PetscBool flg;
47: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
48: PetscViewerFileClose_ASCII(viewer);
49: PetscFree(vascii);
51: /* remove the viewer from the list in the MPI Communicator */
52: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
53: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
54: }
56: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
57: if (flg) {
58: if (vlink && vlink->viewer == viewer) {
59: if (vlink->next) {
60: MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
61: } else {
62: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
63: }
64: PetscFree(vlink);
65: } else {
66: while (vlink && vlink->next) {
67: if (vlink->next->viewer == viewer) {
68: PetscViewerLink *nv = vlink->next;
69: vlink->next = vlink->next->next;
70: PetscFree(nv);
71: }
72: vlink = vlink->next;
73: }
74: }
75: }
77: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
78: PetscViewer aviewer;
79: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
80: if (flg && aviewer == viewer) {
81: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
82: }
83: }
84: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
85: PetscViewer aviewer;
86: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
87: if (flg && aviewer == viewer) {
88: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
89: }
90: }
91: return(0);
92: }
94: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
95: {
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
97: PetscErrorCode ierr;
100: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
101: return(0);
102: }
104: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
105: {
106: PetscErrorCode ierr;
107: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
108: int err;
109: MPI_Comm comm;
110: PetscMPIInt rank,size;
111: FILE *fd = vascii->fd;
114: PetscObjectGetComm((PetscObject)viewer,&comm);
115: MPI_Comm_rank(comm,&rank);
116: MPI_Comm_size(comm,&size);
118: if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
119: err = fflush(vascii->fd);
120: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
121: }
123: if (vascii->allowsynchronized) {
124: PetscMPIInt tag,i,j,n = 0,dummy = 0;
125: char *message;
126: MPI_Status status;
128: PetscCommDuplicate(comm,&comm,&tag);
130: /* First processor waits for messages from all other processors */
131: if (!rank) {
132: /* flush my own messages that I may have queued up */
133: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
134: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
135: if (!vascii->bviewer) {
136: PetscFPrintf(comm,fd,"%s",next->string);
137: } else {
138: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
139: }
140: previous = next;
141: next = next->next;
142: PetscFree(previous->string);
143: PetscFree(previous);
144: }
145: vascii->petsc_printfqueue = 0;
146: vascii->petsc_printfqueuelength = 0;
147: for (i=1; i<size; i++) {
148: /* to prevent a flood of messages to process zero, request each message separately */
149: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
150: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
151: for (j=0; j<n; j++) {
152: PetscMPIInt size = 0;
154: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
155: PetscMalloc1(size, &message);
156: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
157: if (!vascii->bviewer) {
158: PetscFPrintf(comm,fd,"%s",message);
159: } else {
160: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
161: }
162: PetscFree(message);
163: }
164: }
165: } else { /* other processors send queue to processor 0 */
166: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
168: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
169: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
170: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
171: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
172: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
173: previous = next;
174: next = next->next;
175: PetscFree(previous->string);
176: PetscFree(previous);
177: }
178: vascii->petsc_printfqueue = 0;
179: vascii->petsc_printfqueuelength = 0;
180: }
181: PetscCommDestroy(&comm);
182: }
183: return(0);
184: }
186: /*@C
187: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
189: Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
191: Input Parameter:
192: . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
194: Output Parameter:
195: . fd - file pointer
197: Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
199: Level: intermediate
201: Fortran Note:
202: This routine is not supported in Fortran.
204: Concepts: PetscViewer^file pointer
205: Concepts: file pointer^getting from PetscViewer
207: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
208: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
209: @*/
210: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
211: {
212: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
215: *fd = vascii->fd;
216: return(0);
217: }
219: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
220: {
221: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
224: *mode = vascii->mode;
225: return(0);
226: }
228: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
229: {
230: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
233: vascii->mode = mode;
234: return(0);
235: }
237: /*
238: If petsc_history is on, then all Petsc*Printf() results are saved
239: if the appropriate (usually .petschistory) file.
240: */
241: PETSC_INTERN FILE *petsc_history;
243: /*@
244: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
246: Not Collective, but only first processor in set has any effect
248: Input Parameters:
249: + viewer - obtained with PetscViewerASCIIOpen()
250: - tabs - number of tabs
252: Level: developer
254: Fortran Note:
255: This routine is not supported in Fortran.
257: Concepts: PetscViewerASCII^formating
258: Concepts: tab^setting
260: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
261: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
262: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
263: @*/
264: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
265: {
266: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
267: PetscBool iascii;
268: PetscErrorCode ierr;
272: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
273: if (iascii) ascii->tab = tabs;
274: return(0);
275: }
277: /*@
278: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
280: Not Collective, meaningful on first processor only.
282: Input Parameters:
283: . viewer - obtained with PetscViewerASCIIOpen()
284: Output Parameters:
285: . tabs - number of tabs
287: Level: developer
289: Fortran Note:
290: This routine is not supported in Fortran.
292: Concepts: PetscViewerASCII^formating
293: Concepts: tab^retrieval
295: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
296: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
297: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
298: @*/
299: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
300: {
301: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
302: PetscBool iascii;
303: PetscErrorCode ierr;
307: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
308: if (iascii && tabs) *tabs = ascii->tab;
309: return(0);
310: }
312: /*@
313: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
315: Not Collective, but only first processor in set has any effect
317: Input Parameters:
318: + viewer - obtained with PetscViewerASCIIOpen()
319: - tabs - number of tabs
321: Level: developer
323: Fortran Note:
324: This routine is not supported in Fortran.
326: Concepts: PetscViewerASCII^formating
327: Concepts: tab^setting
329: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
330: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
331: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
332: @*/
333: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
334: {
335: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
336: PetscBool iascii;
337: PetscErrorCode ierr;
341: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
342: if (iascii) ascii->tab += tabs;
343: return(0);
344: }
346: /*@
347: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
349: Not Collective, but only first processor in set has any effect
351: Input Parameters:
352: + viewer - obtained with PetscViewerASCIIOpen()
353: - tabs - number of tabs
355: Level: developer
357: Fortran Note:
358: This routine is not supported in Fortran.
360: Concepts: PetscViewerASCII^formating
361: Concepts: tab^setting
363: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
364: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
365: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
366: @*/
367: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
368: {
369: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
370: PetscBool iascii;
371: PetscErrorCode ierr;
375: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
376: if (iascii) ascii->tab -= tabs;
377: return(0);
378: }
380: /*@C
381: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
383: Collective on PetscViewer
385: Input Parameters:
386: . viewer - obtained with PetscViewerASCIIOpen()
388: Level: intermediate
389:
390: Notes:
391: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
393: Concepts: PetscViewerASCII^formating
394: Concepts: tab^setting
396: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
397: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
398: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
399: @*/
400: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
401: {
402: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
403: PetscBool iascii;
404: PetscErrorCode ierr;
408: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
409: if (iascii) ascii->allowsynchronized++;
410: return(0);
411: }
413: /*@C
414: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
416: Collective on PetscViewer
418: Input Parameters:
419: . viewer - obtained with PetscViewerASCIIOpen()
421: Level: intermediate
422:
423: Notes:
424: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
426: Concepts: PetscViewerASCII^formating
427: Concepts: tab^setting
429: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
430: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
431: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
432: @*/
433: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
434: {
435: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
436: PetscBool iascii;
437: PetscErrorCode ierr;
441: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
442: if (iascii) {
443: ascii->allowsynchronized--;
444: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
445: }
446: return(0);
447: }
449: /*@C
450: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
451: lines are tabbed.
453: Not Collective, but only first processor in set has any effect
455: Input Parameters:
456: . viewer - obtained with PetscViewerASCIIOpen()
458: Level: developer
460: Fortran Note:
461: This routine is not supported in Fortran.
463: Concepts: PetscViewerASCII^formating
464: Concepts: tab^setting
466: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
467: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
468: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469: @*/
470: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
471: {
472: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473: PetscBool iascii;
474: PetscErrorCode ierr;
478: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
479: if (iascii) ascii->tab++;
480: return(0);
481: }
483: /*@C
484: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
485: lines are tabbed.
487: Not Collective, but only first processor in set has any effect
489: Input Parameters:
490: . viewer - obtained with PetscViewerASCIIOpen()
492: Level: developer
494: Fortran Note:
495: This routine is not supported in Fortran.
497: Concepts: PetscViewerASCII^formating
498: Concepts: tab^setting
500: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
501: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
502: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
503: @*/
504: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
505: {
506: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
507: PetscErrorCode ierr;
508: PetscBool iascii;
512: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
513: if (iascii) {
514: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
515: ascii->tab--;
516: }
517: return(0);
518: }
520: /*@
521: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
523: Not Collective, but only first processor in set has any effect
525: Input Parameters:
526: + viewer - obtained with PetscViewerASCIIOpen()
527: - flg - PETSC_TRUE or PETSC_FALSE
529: Level: developer
531: Fortran Note:
532: This routine is not supported in Fortran.
534: Concepts: PetscViewerASCII^formating
535: Concepts: tab^setting
537: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
538: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
539: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
540: @*/
541: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
542: {
543: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
544: PetscBool iascii;
545: PetscErrorCode ierr;
549: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
550: if (iascii) {
551: if (flg) ascii->tab = ascii->tab_store;
552: else {
553: ascii->tab_store = ascii->tab;
554: ascii->tab = 0;
555: }
556: }
557: return(0);
558: }
560: /* ----------------------------------------------------------------------- */
563: /*@C
564: PetscViewerASCIIPrintf - Prints to a file, only from the first
565: processor in the PetscViewer
567: Not Collective, but only first processor in set has any effect
569: Input Parameters:
570: + viewer - obtained with PetscViewerASCIIOpen()
571: - format - the usual printf() format string
573: Level: developer
575: Fortran Note:
576: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
577: That is, you can only pass a single character string from Fortran.
579: Concepts: PetscViewerASCII^printing
580: Concepts: printing^to file
581: Concepts: printf
583: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
584: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
585: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
586: @*/
587: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
588: {
589: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
590: PetscMPIInt rank;
591: PetscInt tab,intab = ascii->tab;
592: PetscErrorCode ierr;
593: FILE *fd = ascii->fd;
594: PetscBool iascii;
595: int err;
600: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
601: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
602: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
603: if (rank) return(0);
605: if (ascii->bviewer) { /* pass string up to parent viewer */
606: char *string;
607: va_list Argp;
608: size_t fullLength;
610: PetscCalloc1(QUEUESTRINGSIZE, &string);
611: va_start(Argp,format);
612: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
613: va_end(Argp);
614: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
615: PetscFree(string);
616: } else { /* write directly to file */
617: va_list Argp;
618: /* flush my own messages that I may have queued up */
619: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
620: PetscInt i;
621: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
622: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
623: previous = next;
624: next = next->next;
625: PetscFree(previous->string);
626: PetscFree(previous);
627: }
628: ascii->petsc_printfqueue = 0;
629: ascii->petsc_printfqueuelength = 0;
630: tab = intab;
631: while (tab--) {
632: PetscFPrintf(PETSC_COMM_SELF,fd," ");
633: }
635: va_start(Argp,format);
636: (*PetscVFPrintf)(fd,format,Argp);
637: err = fflush(fd);
638: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
639: if (petsc_history) {
640: va_start(Argp,format);
641: tab = intab;
642: while (tab--) {
643: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
644: }
645: (*PetscVFPrintf)(petsc_history,format,Argp);
646: err = fflush(petsc_history);
647: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
648: }
649: va_end(Argp);
650: }
651: return(0);
652: }
654: /*@C
655: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
657: Collective on PetscViewer
659: Input Parameters:
660: + viewer - the PetscViewer; either ASCII or binary
661: - name - the name of the file it should use
663: Level: advanced
665: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
666: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
668: @*/
669: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
670: {
672: char b[PETSC_MAX_PATH_LEN];
677: PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
678: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
679: return(0);
680: }
682: /*@C
683: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
685: Not Collective
687: Input Parameter:
688: . viewer - the PetscViewer; either ASCII or binary
690: Output Parameter:
691: . name - the name of the file it is using
693: Level: advanced
695: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
697: @*/
698: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
699: {
705: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
706: return(0);
707: }
709: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
710: {
711: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
714: *name = vascii->filename;
715: return(0);
716: }
718: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
719: {
720: PetscErrorCode ierr;
721: size_t len;
722: char fname[PETSC_MAX_PATH_LEN],*gz;
723: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
724: PetscBool isstderr,isstdout;
725: PetscMPIInt rank;
728: PetscViewerFileClose_ASCII(viewer);
729: if (!name) return(0);
730: PetscStrallocpy(name,&vascii->filename);
732: /* Is this file to be compressed */
733: vascii->storecompressed = PETSC_FALSE;
735: PetscStrstr(vascii->filename,".gz",&gz);
736: if (gz) {
737: PetscStrlen(gz,&len);
738: if (len == 3) {
739: 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");
740: *gz = 0;
741: vascii->storecompressed = PETSC_TRUE;
742: }
743: }
744: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
745: if (!rank) {
746: PetscStrcmp(name,"stderr",&isstderr);
747: PetscStrcmp(name,"stdout",&isstdout);
748: /* empty filename means stdout */
749: if (name[0] == 0) isstdout = PETSC_TRUE;
750: if (isstderr) vascii->fd = PETSC_STDERR;
751: else if (isstdout) vascii->fd = PETSC_STDOUT;
752: else {
755: PetscFixFilename(name,fname);
756: switch (vascii->mode) {
757: case FILE_MODE_READ:
758: vascii->fd = fopen(fname,"r");
759: break;
760: case FILE_MODE_WRITE:
761: vascii->fd = fopen(fname,"w");
762: break;
763: case FILE_MODE_APPEND:
764: vascii->fd = fopen(fname,"a");
765: break;
766: case FILE_MODE_UPDATE:
767: vascii->fd = fopen(fname,"r+");
768: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
769: break;
770: case FILE_MODE_APPEND_UPDATE:
771: /* I really want a file which is opened at the end for updating,
772: not a+, which opens at the beginning, but makes writes at the end.
773: */
774: vascii->fd = fopen(fname,"r+");
775: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
776: else {
777: fseek(vascii->fd, 0, SEEK_END);
778: }
779: break;
780: default:
781: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
782: }
783: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
784: }
785: }
786: #if defined(PETSC_USE_LOG)
787: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
788: #endif
789: return(0);
790: }
792: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
793: {
794: PetscMPIInt rank;
795: PetscErrorCode ierr;
796: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
799: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
800: PetscViewerASCIIPushSynchronized(viewer);
801: PetscViewerCreate(subcomm,outviewer);
802: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
803: PetscViewerASCIIPushSynchronized(*outviewer);
804: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
805: ovascii->fd = vascii->fd;
806: ovascii->tab = vascii->tab;
807: ovascii->closefile = PETSC_FALSE;
809: vascii->sviewer = *outviewer;
811: (*outviewer)->format = viewer->format;
813: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
814: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
815: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
816: return(0);
817: }
819: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
820: {
821: PetscErrorCode ierr;
822: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
825: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
826: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
828: ascii->sviewer = 0;
829: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
830: PetscViewerDestroy(outviewer);
831: return(0);
832: }
834: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
835: {
836: PetscErrorCode ierr;
837: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
840: if (ascii->filename) {
841: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
842: }
843: return(0);
844: }
846: /*MC
847: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
850: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
851: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
852: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
854: Level: beginner
856: M*/
857: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
858: {
859: PetscViewer_ASCII *vascii;
860: PetscErrorCode ierr;
863: PetscNewLog(viewer,&vascii);
864: viewer->data = (void*)vascii;
866: viewer->ops->destroy = PetscViewerDestroy_ASCII;
867: viewer->ops->flush = PetscViewerFlush_ASCII;
868: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
869: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
870: viewer->ops->view = PetscViewerView_ASCII;
871: viewer->ops->read = PetscViewerASCIIRead;
873: /* defaults to stdout unless set with PetscViewerFileSetName() */
874: vascii->fd = PETSC_STDOUT;
875: vascii->mode = FILE_MODE_WRITE;
876: vascii->bviewer = 0;
877: vascii->subviewer = 0;
878: vascii->sviewer = 0;
879: vascii->tab = 0;
880: vascii->tab_store = 0;
881: vascii->filename = 0;
882: vascii->closefile = PETSC_TRUE;
884: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
885: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
886: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
887: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
888: return(0);
889: }
891: /*@C
892: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
893: several processors. Output of the first processor is followed by that of the
894: second, etc.
896: Not Collective, must call collective PetscViewerFlush() to get the results out
898: Input Parameters:
899: + viewer - the ASCII PetscViewer
900: - format - the usual printf() format string
902: Level: intermediate
904: Notes:
905: You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
906: Then you can do multiple independent calls to this routine.
907: The actual synchronized print is then done using PetscViewerFlush().
908: PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
909: to conclude the "synchronized session".
910: So the typical calling sequence looks like
911: $ PetscViewerASCIIPushSynchronized(viewer);
912: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
913: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
914: $ ...
915: $ PetscViewerFlush(viewer);
916: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
917: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
918: $ ...
919: $ PetscViewerFlush(viewer);
920: $ PetscViewerASCIIPopSynchronized(viewer);
922: Fortran Note:
923: Can only print a single character* string
925: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
926: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
927: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
928: @*/
929: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
930: {
931: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
932: PetscErrorCode ierr;
933: PetscMPIInt rank;
934: PetscInt tab = vascii->tab;
935: MPI_Comm comm;
936: FILE *fp;
937: PetscBool iascii,hasbviewer = PETSC_FALSE;
938: int err;
943: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
944: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
945: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
947: PetscObjectGetComm((PetscObject)viewer,&comm);
948: MPI_Comm_rank(comm,&rank);
950: if (vascii->bviewer) {
951: hasbviewer = PETSC_TRUE;
952: if (!rank) {
953: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
954: PetscObjectGetComm((PetscObject)viewer,&comm);
955: MPI_Comm_rank(comm,&rank);
956: }
957: }
959: fp = vascii->fd;
961: if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
962: va_list Argp;
963: /* flush my own messages that I may have queued up */
964: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
965: PetscInt i;
966: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
967: PetscFPrintf(comm,fp,"%s",next->string);
968: previous = next;
969: next = next->next;
970: PetscFree(previous->string);
971: PetscFree(previous);
972: }
973: vascii->petsc_printfqueue = 0;
974: vascii->petsc_printfqueuelength = 0;
976: while (tab--) {
977: PetscFPrintf(PETSC_COMM_SELF,fp," ");
978: }
980: va_start(Argp,format);
981: (*PetscVFPrintf)(fp,format,Argp);
982: err = fflush(fp);
983: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
984: if (petsc_history) {
985: va_start(Argp,format);
986: (*PetscVFPrintf)(petsc_history,format,Argp);
987: err = fflush(petsc_history);
988: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
989: }
990: va_end(Argp);
991: } else { /* other processors add to queue */
992: char *string;
993: va_list Argp;
994: size_t fullLength;
995: PrintfQueue next;
997: PetscNew(&next);
998: if (vascii->petsc_printfqueue) {
999: vascii->petsc_printfqueue->next = next;
1000: vascii->petsc_printfqueue = next;
1001: } else {
1002: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
1003: }
1004: vascii->petsc_printfqueuelength++;
1005: next->size = QUEUESTRINGSIZE;
1006: PetscMalloc1(next->size, &next->string);
1007: PetscMemzero(next->string,next->size);
1008: string = next->string;
1009: tab *= 2;
1010: while (tab--) {
1011: *string++ = ' ';
1012: }
1013: va_start(Argp,format);
1014: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1015: va_end(Argp);
1016: if (fullLength > (size_t) (next->size-2*vascii->tab)) {
1017: PetscFree(next->string);
1018: next->size = fullLength + 2*vascii->tab;
1019: PetscMalloc1(next->size, &next->string);
1020: PetscMemzero(next->string,next->size);
1021: string = next->string;
1022: tab = 2*vascii->tab;
1023: while (tab--) {
1024: *string++ = ' ';
1025: }
1026: va_start(Argp,format);
1027: PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1028: va_end(Argp);
1029: }
1030: }
1031: return(0);
1032: }
1034: /*@C
1035: PetscViewerASCIIRead - Reads from a ASCII file
1037: Only process 0 in the PetscViewer may call this
1039: Input Parameters:
1040: + viewer - the ascii viewer
1041: . data - location to write the data
1042: . num - number of items of data to read
1043: - datatype - type of data to read
1045: Output Parameters:
1046: . count - number of items of data actually read, or NULL
1048: Level: beginner
1050: Concepts: ascii files
1052: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1053: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1054: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1055: @*/
1056: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1057: {
1058: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1059: FILE *fd = vascii->fd;
1060: PetscInt i;
1061: int ret = 0;
1062: PetscMPIInt rank;
1063: PetscErrorCode ierr;
1067: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1068: if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1069: for (i=0; i<num; i++) {
1070: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1071: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1072: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1073: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1074: else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i]));
1075: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1076: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1077: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1078: #if defined(PETSC_USE_REAL___FLOAT128)
1079: else if (dtype == PETSC___FLOAT128) {
1080: double tmp;
1081: ret = fscanf(fd, "%lg", &tmp);
1082: ((__float128*)data)[i] = tmp;
1083: }
1084: #endif
1085: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1086: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1087: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1088: }
1089: if (count) *count = i;
1090: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1091: return(0);
1092: }