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: PetscMPIInt rank;
9: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
10: int err;
12: PetscFunctionBegin;
13: PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
14: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
15: if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
16: if (vascii->fd && vascii->closefile) {
17: err = fclose(vascii->fd);
18: PetscCheck(!err, 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: PetscCall(PetscStrncpy(par, "gzip ", sizeof(par)));
24: PetscCall(PetscStrlcat(par, vascii->filename, sizeof(par)));
25: #if defined(PETSC_HAVE_POPEN)
26: PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, par, "r", &fp));
27: PetscCheck(!fgets(buf, 1024, fp), PETSC_COMM_SELF, PETSC_ERR_LIB, "Error from compression command %s\n%s", par, buf);
28: PetscCall(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: PetscCall(PetscFree(vascii->filename));
35: PetscFunctionReturn(PETSC_SUCCESS);
36: }
38: /* ----------------------------------------------------------------------*/
39: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
40: {
41: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
42: PetscViewerLink *vlink;
43: PetscBool flg;
45: PetscFunctionBegin;
46: PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
47: PetscCall(PetscViewerFileClose_ASCII(viewer));
48: PetscCall(PetscFree(vascii));
50: /* remove the viewer from the list in the MPI Communicator */
51: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, (void *)0));
53: PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
54: if (flg) {
55: if (vlink && vlink->viewer == viewer) {
56: if (vlink->next) {
57: PetscCallMPI(MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, vlink->next));
58: } else {
59: PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval));
60: }
61: PetscCall(PetscFree(vlink));
62: } else {
63: while (vlink && vlink->next) {
64: if (vlink->next->viewer == viewer) {
65: PetscViewerLink *nv = vlink->next;
66: vlink->next = vlink->next->next;
67: PetscCall(PetscFree(nv));
68: }
69: vlink = vlink->next;
70: }
71: }
72: }
74: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
75: PetscViewer aviewer;
76: PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval, (void **)&aviewer, (PetscMPIInt *)&flg));
77: if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval));
78: }
79: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
80: PetscViewer aviewer;
81: PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval, (void **)&aviewer, (PetscMPIInt *)&flg));
82: if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval));
83: }
84: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL));
85: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL));
86: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL));
87: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL));
88: PetscFunctionReturn(PETSC_SUCCESS);
89: }
91: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
92: {
93: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
95: PetscFunctionBegin;
96: PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer, 0, &viewer));
97: PetscFunctionReturn(PETSC_SUCCESS);
98: }
100: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
101: {
102: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
103: MPI_Comm comm;
104: PetscMPIInt rank, size;
105: FILE *fd = vascii->fd;
107: PetscFunctionBegin;
108: PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
109: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
110: PetscCallMPI(MPI_Comm_rank(comm, &rank));
111: PetscCallMPI(MPI_Comm_size(comm, &size));
113: if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) PetscCall(PetscFFlush(vascii->fd));
115: if (vascii->allowsynchronized) {
116: PetscMPIInt tag, i, j, n = 0, dummy = 0;
117: char *message;
118: MPI_Status status;
120: PetscCall(PetscCommDuplicate(comm, &comm, &tag));
122: /* First processor waits for messages from all other processors */
123: if (rank == 0) {
124: /* flush my own messages that I may have queued up */
125: PrintfQueue next = vascii->petsc_printfqueuebase, previous;
126: for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
127: if (!vascii->bviewer) {
128: PetscCall(PetscFPrintf(comm, fd, "%s", next->string));
129: } else {
130: PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", next->string));
131: }
132: previous = next;
133: next = next->next;
134: PetscCall(PetscFree(previous->string));
135: PetscCall(PetscFree(previous));
136: }
137: vascii->petsc_printfqueue = NULL;
138: vascii->petsc_printfqueuelength = 0;
139: for (i = 1; i < size; i++) {
140: /* to prevent a flood of messages to process zero, request each message separately */
141: PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
142: PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
143: for (j = 0; j < n; j++) {
144: PetscMPIInt size = 0;
146: PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status));
147: PetscCall(PetscMalloc1(size, &message));
148: PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status));
149: if (!vascii->bviewer) {
150: PetscCall(PetscFPrintf(comm, fd, "%s", message));
151: } else {
152: PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", message));
153: }
154: PetscCall(PetscFree(message));
155: }
156: }
157: } else { /* other processors send queue to processor 0 */
158: PrintfQueue next = vascii->petsc_printfqueuebase, previous;
160: PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
161: PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
162: for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
163: PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm));
164: PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm));
165: previous = next;
166: next = next->next;
167: PetscCall(PetscFree(previous->string));
168: PetscCall(PetscFree(previous));
169: }
170: vascii->petsc_printfqueue = NULL;
171: vascii->petsc_printfqueuelength = 0;
172: }
173: PetscCall(PetscCommDestroy(&comm));
174: }
175: PetscFunctionReturn(PETSC_SUCCESS);
176: }
178: /*@C
179: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII `PetscViewer`.
181: Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer; No Fortran Support
183: Input Parameter:
184: . viewer - `PetscViewer` context, obtained from `PetscViewerASCIIOpen()`
186: Output Parameter:
187: . fd - file pointer
189: Level: intermediate
191: Note:
192: For the standard `PETSCVIEWERASCII` the value is valid only on process 0 of the viewer
194: .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`,
195: `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
196: @*/
197: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd)
198: {
199: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
201: PetscFunctionBegin;
202: *fd = vascii->fd;
203: PetscFunctionReturn(PETSC_SUCCESS);
204: }
206: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
207: {
208: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
210: PetscFunctionBegin;
211: *mode = vascii->mode;
212: PetscFunctionReturn(PETSC_SUCCESS);
213: }
215: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
216: {
217: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
219: PetscFunctionBegin;
220: vascii->mode = mode;
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: /*
225: If petsc_history is on, then all Petsc*Printf() results are saved
226: if the appropriate (usually .petschistory) file.
227: */
228: PETSC_INTERN FILE *petsc_history;
230: /*@
231: PetscViewerASCIISetTab - Causes `PetscViewer` to tab in a number of times before printing
233: Not Collective, but only first processor in set has any effect; No Fortran Support
235: Input Parameters:
236: + viewer - obtained with `PetscViewerASCIIOpen()`
237: - tabs - number of tabs
239: Level: developer
241: Note:
242: `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
244: .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
245: `PetscViewerASCIIGetTab()`,
246: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
247: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`,
248: `PetscViewerASCIIPushTab()`
249: @*/
250: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs)
251: {
252: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
253: PetscBool iascii;
255: PetscFunctionBegin;
257: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
258: if (iascii) ascii->tab = tabs;
259: PetscFunctionReturn(PETSC_SUCCESS);
260: }
262: /*@
263: PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`.
265: Not Collective, meaningful on first processor only; No Fortran Support
267: Input Parameter:
268: . viewer - obtained with `PetscViewerASCIIOpen()`
270: Output Parameter:
271: . tabs - number of tabs
273: Level: developer
275: .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
276: `PetscViewerASCIISetTab()`,
277: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
278: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
279: @*/
280: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs)
281: {
282: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
283: PetscBool iascii;
285: PetscFunctionBegin;
287: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
288: if (iascii && tabs) *tabs = ascii->tab;
289: PetscFunctionReturn(PETSC_SUCCESS);
290: }
292: /*@
293: PetscViewerASCIIAddTab - Add to the number of times a `PETSCVIEWERASCII` viewer tabs before printing
295: Not Collective, but only first processor in set has any effect; No Fortran Support
297: Input Parameters:
298: + viewer - obtained with `PetscViewerASCIIOpen()`
299: - tabs - number of tabs
301: Level: developer
303: Note:
304: `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
306: .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
307: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
308: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
309: @*/
310: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs)
311: {
312: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
313: PetscBool iascii;
315: PetscFunctionBegin;
317: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
318: if (iascii) ascii->tab += tabs;
319: PetscFunctionReturn(PETSC_SUCCESS);
320: }
322: /*@
323: PetscViewerASCIISubtractTab - Subtracts from the number of times a `PETSCVIEWERASCII` viewer tabs before printing
325: Not Collective, but only first processor in set has any effect; No Fortran Support
327: Input Parameters:
328: + viewer - obtained with `PetscViewerASCIIOpen()`
329: - tabs - number of tabs
331: Level: developer
333: Note:
334: `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
336: .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
337: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
338: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`,
339: `PetscViewerASCIIPushTab()`
340: @*/
341: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs)
342: {
343: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
344: PetscBool iascii;
346: PetscFunctionBegin;
348: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
349: if (iascii) ascii->tab -= tabs;
350: PetscFunctionReturn(PETSC_SUCCESS);
351: }
353: /*@C
354: PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer
356: Collective
358: Input Parameter:
359: . viewer - obtained with `PetscViewerASCIIOpen()`
361: Level: intermediate
363: Note:
364: See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
366: .seealso: [](sec_viewers), `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
367: `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
368: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
369: @*/
370: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
371: {
372: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
373: PetscBool iascii;
375: PetscFunctionBegin;
377: PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
378: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
379: if (iascii) ascii->allowsynchronized++;
380: PetscFunctionReturn(PETSC_SUCCESS);
381: }
383: /*@C
384: PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer
386: Collective
388: Input Parameter:
389: . viewer - obtained with `PetscViewerASCIIOpen()`
391: Level: intermediate
393: Note:
394: See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
396: .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
397: `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
398: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
399: @*/
400: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
401: {
402: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
403: PetscBool iascii;
405: PetscFunctionBegin;
407: PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
408: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
409: if (iascii) {
410: ascii->allowsynchronized--;
411: PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
412: }
413: PetscFunctionReturn(PETSC_SUCCESS);
414: }
416: /*@C
417: PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()`
418: lines are tabbed.
420: Not Collective, but only first processor in set has any effect; No Fortran Support
422: Input Parameter:
423: . viewer - obtained with `PetscViewerASCIIOpen()`
425: Level: developer
427: .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
428: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
429: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
430: @*/
431: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
432: {
433: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
434: PetscBool iascii;
436: PetscFunctionBegin;
438: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
439: if (iascii) ascii->tab++;
440: PetscFunctionReturn(PETSC_SUCCESS);
441: }
443: /*@C
444: PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by
445: `PetscViewerASCIIPushTab()`
447: Not Collective, but only first processor in set has any effect; No Fortran Support
449: Input Parameter:
450: . viewer - obtained with `PetscViewerASCIIOpen()`
452: Level: developer
454: .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
455: `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
456: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
457: @*/
458: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
459: {
460: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
461: PetscBool iascii;
463: PetscFunctionBegin;
465: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
466: if (iascii) {
467: PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed");
468: ascii->tab--;
469: }
470: PetscFunctionReturn(PETSC_SUCCESS);
471: }
473: /*@
474: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII `PetscViewer`
476: Not Collective, but only first processor in set has any effect; No Fortran Support
478: Input Parameters:
479: + viewer - obtained with `PetscViewerASCIIOpen()`
480: - flg - `PETSC_TRUE` or `PETSC_FALSE`
482: Level: developer
484: .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
485: `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
486: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
487: @*/
488: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg)
489: {
490: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
491: PetscBool iascii;
493: PetscFunctionBegin;
495: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
496: if (iascii) {
497: if (flg) ascii->tab = ascii->tab_store;
498: else {
499: ascii->tab_store = ascii->tab;
500: ascii->tab = 0;
501: }
502: }
503: PetscFunctionReturn(PETSC_SUCCESS);
504: }
506: /* ----------------------------------------------------------------------- */
508: /*@C
509: PetscViewerASCIIPrintf - Prints to a file, only from the first
510: processor in the `PetscViewer` of type `PETSCVIEWERASCII`
512: Not Collective, but only first processor in set has any effect
514: Input Parameters:
515: + viewer - obtained with `PetscViewerASCIIOpen()`
516: - format - the usual printf() format string
518: Level: developer
520: Fortran Note:
521: The call sequence is `PetscViewerASCIIPrintf`(PetscViewer, character(*), int ierr) from Fortran.
522: That is, you can only pass a single character string from Fortran.
524: .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
525: `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
526: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
527: @*/
528: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...)
529: {
530: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
531: PetscMPIInt rank;
532: PetscInt tab, intab = ascii->tab;
533: FILE *fd = ascii->fd;
534: PetscBool iascii;
536: PetscFunctionBegin;
538: PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
540: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
541: PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
542: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
543: if (rank) PetscFunctionReturn(PETSC_SUCCESS);
545: if (ascii->bviewer) { /* pass string up to parent viewer */
546: char *string;
547: va_list Argp;
548: size_t fullLength;
550: PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
551: va_start(Argp, format);
552: PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp));
553: va_end(Argp);
554: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string));
555: PetscCall(PetscFree(string));
556: } else { /* write directly to file */
557: va_list Argp;
558: /* flush my own messages that I may have queued up */
559: PrintfQueue next = ascii->petsc_printfqueuebase, previous;
560: PetscInt i;
561: for (i = 0; i < ascii->petsc_printfqueuelength; i++) {
562: PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string));
563: previous = next;
564: next = next->next;
565: PetscCall(PetscFree(previous->string));
566: PetscCall(PetscFree(previous));
567: }
568: ascii->petsc_printfqueue = NULL;
569: ascii->petsc_printfqueuelength = 0;
570: tab = intab;
571: while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, " "));
573: va_start(Argp, format);
574: PetscCall((*PetscVFPrintf)(fd, format, Argp));
575: va_end(Argp);
576: PetscCall(PetscFFlush(fd));
577: if (petsc_history) {
578: tab = intab;
579: while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, " "));
580: va_start(Argp, format);
581: PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
582: va_end(Argp);
583: PetscCall(PetscFFlush(petsc_history));
584: }
585: }
586: PetscFunctionReturn(PETSC_SUCCESS);
587: }
589: /*@C
590: PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
592: Collective
594: Input Parameters:
595: + viewer - the `PetscViewer`; for example, of type `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
596: - name - the name of the file it should use
598: Level: advanced
600: .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
601: `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
602: @*/
603: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
604: {
605: char filename[PETSC_MAX_PATH_LEN];
607: PetscFunctionBegin;
610: PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
611: PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
612: PetscFunctionReturn(PETSC_SUCCESS);
613: }
615: /*@C
616: PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
618: Not Collective
620: Input Parameter:
621: . viewer - the `PetscViewer`
623: Output Parameter:
624: . name - the name of the file it is using
626: Level: advanced
628: .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
629: @*/
630: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name)
631: {
632: PetscFunctionBegin;
635: PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
636: PetscFunctionReturn(PETSC_SUCCESS);
637: }
639: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
640: {
641: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
643: PetscFunctionBegin;
644: *name = vascii->filename;
645: PetscFunctionReturn(PETSC_SUCCESS);
646: }
648: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
649: {
650: size_t len;
651: char fname[PETSC_MAX_PATH_LEN], *gz = NULL;
652: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
653: PetscBool isstderr, isstdout;
654: PetscMPIInt rank;
656: PetscFunctionBegin;
657: PetscCall(PetscViewerFileClose_ASCII(viewer));
658: if (!name) PetscFunctionReturn(PETSC_SUCCESS);
659: PetscCall(PetscStrallocpy(name, &vascii->filename));
661: /* Is this file to be compressed */
662: vascii->storecompressed = PETSC_FALSE;
664: PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
665: if (gz) {
666: PetscCall(PetscStrlen(gz, &len));
667: if (len == 3) {
668: PetscCheck(vascii->mode == FILE_MODE_WRITE, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
669: *gz = 0;
670: vascii->storecompressed = PETSC_TRUE;
671: }
672: }
673: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
674: if (rank == 0) {
675: PetscCall(PetscStrcmp(name, "stderr", &isstderr));
676: PetscCall(PetscStrcmp(name, "stdout", &isstdout));
677: /* empty filename means stdout */
678: if (name[0] == 0) isstdout = PETSC_TRUE;
679: if (isstderr) vascii->fd = PETSC_STDERR;
680: else if (isstdout) vascii->fd = PETSC_STDOUT;
681: else {
682: PetscCall(PetscFixFilename(name, fname));
683: switch (vascii->mode) {
684: case FILE_MODE_READ:
685: vascii->fd = fopen(fname, "r");
686: break;
687: case FILE_MODE_WRITE:
688: vascii->fd = fopen(fname, "w");
689: break;
690: case FILE_MODE_APPEND:
691: vascii->fd = fopen(fname, "a");
692: break;
693: case FILE_MODE_UPDATE:
694: vascii->fd = fopen(fname, "r+");
695: if (!vascii->fd) vascii->fd = fopen(fname, "w+");
696: break;
697: case FILE_MODE_APPEND_UPDATE:
698: /* I really want a file which is opened at the end for updating,
699: not a+, which opens at the beginning, but makes writes at the end.
700: */
701: vascii->fd = fopen(fname, "r+");
702: if (!vascii->fd) vascii->fd = fopen(fname, "w+");
703: else {
704: int ret = fseek(vascii->fd, 0, SEEK_END);
705: PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
706: }
707: break;
708: default:
709: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
710: }
711: PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
712: }
713: }
714: #if defined(PETSC_USE_LOG)
715: PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
716: #endif
717: PetscFunctionReturn(PETSC_SUCCESS);
718: }
720: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
721: {
722: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
724: PetscFunctionBegin;
725: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
726: PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
727: /*
728: The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
729: because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
730: (since the count never gets to zero) in some examples this displays information that otherwise would be lost
732: This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
733: PCView_GASM().
734: */
735: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
736: PetscCall(PetscViewerCreate(subcomm, outviewer));
737: PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
738: PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
739: ovascii = (PetscViewer_ASCII *)(*outviewer)->data;
740: ovascii->fd = vascii->fd;
741: ovascii->tab = vascii->tab;
742: ovascii->closefile = PETSC_FALSE;
744: vascii->sviewer = *outviewer;
745: (*outviewer)->format = viewer->format;
746: ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
747: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
748: PetscFunctionReturn(PETSC_SUCCESS);
749: }
751: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
752: {
753: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
755: PetscFunctionBegin;
756: PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
757: PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
759: PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
760: ascii->sviewer = NULL;
761: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
762: PetscCall(PetscViewerDestroy(outviewer));
763: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
764: PetscFunctionReturn(PETSC_SUCCESS);
765: }
767: PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
768: {
769: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
771: PetscFunctionBegin;
772: if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
773: PetscFunctionReturn(PETSC_SUCCESS);
774: }
776: /*MC
777: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
779: Level: beginner
781: .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
782: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
783: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
784: M*/
785: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
786: {
787: PetscViewer_ASCII *vascii;
789: PetscFunctionBegin;
790: PetscCall(PetscNew(&vascii));
791: viewer->data = (void *)vascii;
793: viewer->ops->destroy = PetscViewerDestroy_ASCII;
794: viewer->ops->flush = PetscViewerFlush_ASCII;
795: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
796: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
797: viewer->ops->view = PetscViewerView_ASCII;
798: viewer->ops->read = PetscViewerASCIIRead;
800: /* defaults to stdout unless set with PetscViewerFileSetName() */
801: vascii->fd = PETSC_STDOUT;
802: vascii->mode = FILE_MODE_WRITE;
803: vascii->bviewer = NULL;
804: vascii->subviewer = NULL;
805: vascii->sviewer = NULL;
806: vascii->tab = 0;
807: vascii->tab_store = 0;
808: vascii->filename = NULL;
809: vascii->closefile = PETSC_TRUE;
811: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
812: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
813: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
814: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
815: PetscFunctionReturn(PETSC_SUCCESS);
816: }
818: /*@C
819: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
820: several processors. Output of the first processor is followed by that of the
821: second, etc.
823: Not Collective, must call collective `PetscViewerFlush()` to get the results out
825: Input Parameters:
826: + viewer - the `PETSCVIEWERASCII` `PetscViewer`
827: - format - the usual printf() format string
829: Level: intermediate
831: Notes:
832: You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
833: Then you can do multiple independent calls to this routine.
835: The actual synchronized print is then done using `PetscViewerFlush()`.
836: `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
837: to conclude the "synchronized session".
839: So the typical calling sequence looks like
840: .vb
841: PetscViewerASCIIPushSynchronized(viewer);
842: PetscViewerASCIISynchronizedPrintf(viewer, ...);
843: PetscViewerASCIISynchronizedPrintf(viewer, ...);
844: ...
845: PetscViewerFlush(viewer);
846: PetscViewerASCIISynchronizedPrintf(viewer, ...);
847: PetscViewerASCIISynchronizedPrintf(viewer, ...);
848: ...
849: PetscViewerFlush(viewer);
850: PetscViewerASCIIPopSynchronized(viewer);
851: .ve
853: Fortran Note:
854: Can only print a single character* string
856: .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
857: `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
858: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
859: @*/
860: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
861: {
862: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
863: PetscMPIInt rank;
864: PetscInt tab = vascii->tab;
865: MPI_Comm comm;
866: FILE *fp;
867: PetscBool iascii, hasbviewer = PETSC_FALSE;
869: PetscFunctionBegin;
872: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
873: PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
874: PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
876: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
877: PetscCallMPI(MPI_Comm_rank(comm, &rank));
879: if (vascii->bviewer) {
880: hasbviewer = PETSC_TRUE;
881: if (rank == 0) {
882: vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
883: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
884: PetscCallMPI(MPI_Comm_rank(comm, &rank));
885: }
886: }
888: fp = vascii->fd;
890: if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
891: va_list Argp;
892: /* flush my own messages that I may have queued up */
893: PrintfQueue next = vascii->petsc_printfqueuebase, previous;
894: PetscInt i;
895: for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
896: PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
897: previous = next;
898: next = next->next;
899: PetscCall(PetscFree(previous->string));
900: PetscCall(PetscFree(previous));
901: }
902: vascii->petsc_printfqueue = NULL;
903: vascii->petsc_printfqueuelength = 0;
905: while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " "));
907: va_start(Argp, format);
908: PetscCall((*PetscVFPrintf)(fp, format, Argp));
909: va_end(Argp);
910: PetscCall(PetscFFlush(fp));
911: if (petsc_history) {
912: va_start(Argp, format);
913: PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
914: va_end(Argp);
915: PetscCall(PetscFFlush(petsc_history));
916: }
917: va_end(Argp);
918: } else { /* other processors add to queue */
919: char *string;
920: va_list Argp;
921: size_t fullLength;
922: PrintfQueue next;
924: PetscCall(PetscNew(&next));
925: if (vascii->petsc_printfqueue) {
926: vascii->petsc_printfqueue->next = next;
927: vascii->petsc_printfqueue = next;
928: } else {
929: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
930: }
931: vascii->petsc_printfqueuelength++;
932: next->size = QUEUESTRINGSIZE;
933: PetscCall(PetscCalloc1(next->size, &next->string));
934: string = next->string;
935: tab *= 2;
936: while (tab--) *string++ = ' ';
937: va_start(Argp, format);
938: PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
939: va_end(Argp);
940: if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
941: PetscCall(PetscFree(next->string));
942: next->size = fullLength + 2 * vascii->tab;
943: PetscCall(PetscCalloc1(next->size, &next->string));
944: string = next->string;
945: tab = 2 * vascii->tab;
946: while (tab--) *string++ = ' ';
947: va_start(Argp, format);
948: PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
949: va_end(Argp);
950: }
951: }
952: PetscFunctionReturn(PETSC_SUCCESS);
953: }
955: /*@C
956: PetscViewerASCIIRead - Reads from a ASCII file
958: Only process 0 in the `PetscViewer` may call this
960: Input Parameters:
961: + viewer - the `PETSCVIEWERASCII` viewer
962: . data - location to write the data
963: . num - number of items of data to read
964: - datatype - type of data to read
966: Output Parameter:
967: . count - number of items of data actually read, or `NULL`
969: Level: beginner
971: .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
972: `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
973: `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
974: @*/
975: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
976: {
977: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
978: FILE *fd = vascii->fd;
979: PetscInt i;
980: int ret = 0;
981: PetscMPIInt rank;
983: PetscFunctionBegin;
985: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
986: PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
987: for (i = 0; i < num; i++) {
988: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
989: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
990: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
991: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
992: else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
993: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
994: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
995: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
996: #if defined(PETSC_USE_REAL___FLOAT128)
997: else if (dtype == PETSC___FLOAT128) {
998: double tmp;
999: ret = fscanf(fd, "%lg", &tmp);
1000: ((__float128 *)data)[i] = tmp;
1001: }
1002: #endif
1003: else
1004: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
1005: PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
1006: if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1007: }
1008: if (count) *count = i;
1009: else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
1010: PetscFunctionReturn(PETSC_SUCCESS);
1011: }