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 Parameters:
268: . viewer - obtained with `PetscViewerASCIIOpen()`
270: Output Parameters:
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 Parameters:
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 Parameters:
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 Parameters:
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 Parameters:
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: PetscCall(PetscFFlush(fd));
576: if (petsc_history) {
577: va_start(Argp, format);
578: tab = intab;
579: while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, " "));
580: PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
581: PetscCall(PetscFFlush(petsc_history));
582: }
583: va_end(Argp);
584: }
585: PetscFunctionReturn(PETSC_SUCCESS);
586: }
588: /*@C
589: PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
591: Collective
593: Input Parameters:
594: + viewer - the `PetscViewer`; for example, of type `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
595: - name - the name of the file it should use
597: Level: advanced
599: .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
600: `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
601: @*/
602: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
603: {
604: char filename[PETSC_MAX_PATH_LEN];
606: PetscFunctionBegin;
609: PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
610: PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
611: PetscFunctionReturn(PETSC_SUCCESS);
612: }
614: /*@C
615: PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
617: Not Collective
619: Input Parameter:
620: . viewer - the `PetscViewer`
622: Output Parameter:
623: . name - the name of the file it is using
625: Level: advanced
627: .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
628: @*/
629: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name)
630: {
631: PetscFunctionBegin;
634: PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
635: PetscFunctionReturn(PETSC_SUCCESS);
636: }
638: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
639: {
640: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
642: PetscFunctionBegin;
643: *name = vascii->filename;
644: PetscFunctionReturn(PETSC_SUCCESS);
645: }
647: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
648: {
649: size_t len;
650: char fname[PETSC_MAX_PATH_LEN], *gz = NULL;
651: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
652: PetscBool isstderr, isstdout;
653: PetscMPIInt rank;
655: PetscFunctionBegin;
656: PetscCall(PetscViewerFileClose_ASCII(viewer));
657: if (!name) PetscFunctionReturn(PETSC_SUCCESS);
658: PetscCall(PetscStrallocpy(name, &vascii->filename));
660: /* Is this file to be compressed */
661: vascii->storecompressed = PETSC_FALSE;
663: PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
664: if (gz) {
665: PetscCall(PetscStrlen(gz, &len));
666: if (len == 3) {
667: PetscCheck(vascii->mode == FILE_MODE_WRITE, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
668: *gz = 0;
669: vascii->storecompressed = PETSC_TRUE;
670: }
671: }
672: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
673: if (rank == 0) {
674: PetscCall(PetscStrcmp(name, "stderr", &isstderr));
675: PetscCall(PetscStrcmp(name, "stdout", &isstdout));
676: /* empty filename means stdout */
677: if (name[0] == 0) isstdout = PETSC_TRUE;
678: if (isstderr) vascii->fd = PETSC_STDERR;
679: else if (isstdout) vascii->fd = PETSC_STDOUT;
680: else {
681: PetscCall(PetscFixFilename(name, fname));
682: switch (vascii->mode) {
683: case FILE_MODE_READ:
684: vascii->fd = fopen(fname, "r");
685: break;
686: case FILE_MODE_WRITE:
687: vascii->fd = fopen(fname, "w");
688: break;
689: case FILE_MODE_APPEND:
690: vascii->fd = fopen(fname, "a");
691: break;
692: case FILE_MODE_UPDATE:
693: vascii->fd = fopen(fname, "r+");
694: if (!vascii->fd) vascii->fd = fopen(fname, "w+");
695: break;
696: case FILE_MODE_APPEND_UPDATE:
697: /* I really want a file which is opened at the end for updating,
698: not a+, which opens at the beginning, but makes writes at the end.
699: */
700: vascii->fd = fopen(fname, "r+");
701: if (!vascii->fd) vascii->fd = fopen(fname, "w+");
702: else {
703: int ret = fseek(vascii->fd, 0, SEEK_END);
704: PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
705: }
706: break;
707: default:
708: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
709: }
710: PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
711: }
712: }
713: #if defined(PETSC_USE_LOG)
714: PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
715: #endif
716: PetscFunctionReturn(PETSC_SUCCESS);
717: }
719: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
720: {
721: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
723: PetscFunctionBegin;
724: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
725: PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
726: /*
727: The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
728: because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
729: (since the count never gets to zero) in some examples this displays information that otherwise would be lost
731: This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
732: PCView_GASM().
733: */
734: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
735: PetscCall(PetscViewerCreate(subcomm, outviewer));
736: PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
737: PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
738: ovascii = (PetscViewer_ASCII *)(*outviewer)->data;
739: ovascii->fd = vascii->fd;
740: ovascii->tab = vascii->tab;
741: ovascii->closefile = PETSC_FALSE;
743: vascii->sviewer = *outviewer;
744: (*outviewer)->format = viewer->format;
745: ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
746: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
747: PetscFunctionReturn(PETSC_SUCCESS);
748: }
750: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
751: {
752: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
754: PetscFunctionBegin;
755: PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
756: PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
758: PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
759: ascii->sviewer = NULL;
760: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
761: PetscCall(PetscViewerDestroy(outviewer));
762: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
763: PetscFunctionReturn(PETSC_SUCCESS);
764: }
766: PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
767: {
768: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
770: PetscFunctionBegin;
771: if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
772: PetscFunctionReturn(PETSC_SUCCESS);
773: }
775: /*MC
776: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
778: Level: beginner
780: .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
781: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
782: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
783: M*/
784: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
785: {
786: PetscViewer_ASCII *vascii;
788: PetscFunctionBegin;
789: PetscCall(PetscNew(&vascii));
790: viewer->data = (void *)vascii;
792: viewer->ops->destroy = PetscViewerDestroy_ASCII;
793: viewer->ops->flush = PetscViewerFlush_ASCII;
794: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
795: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
796: viewer->ops->view = PetscViewerView_ASCII;
797: viewer->ops->read = PetscViewerASCIIRead;
799: /* defaults to stdout unless set with PetscViewerFileSetName() */
800: vascii->fd = PETSC_STDOUT;
801: vascii->mode = FILE_MODE_WRITE;
802: vascii->bviewer = NULL;
803: vascii->subviewer = NULL;
804: vascii->sviewer = NULL;
805: vascii->tab = 0;
806: vascii->tab_store = 0;
807: vascii->filename = NULL;
808: vascii->closefile = PETSC_TRUE;
810: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
811: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
812: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
813: PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
814: PetscFunctionReturn(PETSC_SUCCESS);
815: }
817: /*@C
818: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
819: several processors. Output of the first processor is followed by that of the
820: second, etc.
822: Not Collective, must call collective `PetscViewerFlush()` to get the results out
824: Input Parameters:
825: + viewer - the `PETSCVIEWERASCII` `PetscViewer`
826: - format - the usual printf() format string
828: Level: intermediate
830: Notes:
831: You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
832: Then you can do multiple independent calls to this routine.
834: The actual synchronized print is then done using `PetscViewerFlush()`.
835: `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
836: to conclude the "synchronized session".
838: So the typical calling sequence looks like
839: .vb
840: PetscViewerASCIIPushSynchronized(viewer);
841: PetscViewerASCIISynchronizedPrintf(viewer, ...);
842: PetscViewerASCIISynchronizedPrintf(viewer, ...);
843: ...
844: PetscViewerFlush(viewer);
845: PetscViewerASCIISynchronizedPrintf(viewer, ...);
846: PetscViewerASCIISynchronizedPrintf(viewer, ...);
847: ...
848: PetscViewerFlush(viewer);
849: PetscViewerASCIIPopSynchronized(viewer);
850: .ve
852: Fortran Note:
853: Can only print a single character* string
855: .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
856: `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
857: `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
858: @*/
859: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
860: {
861: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
862: PetscMPIInt rank;
863: PetscInt tab = vascii->tab;
864: MPI_Comm comm;
865: FILE *fp;
866: PetscBool iascii, hasbviewer = PETSC_FALSE;
868: PetscFunctionBegin;
871: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
872: PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
873: PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
875: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
876: PetscCallMPI(MPI_Comm_rank(comm, &rank));
878: if (vascii->bviewer) {
879: hasbviewer = PETSC_TRUE;
880: if (rank == 0) {
881: vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
882: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
883: PetscCallMPI(MPI_Comm_rank(comm, &rank));
884: }
885: }
887: fp = vascii->fd;
889: if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
890: va_list Argp;
891: /* flush my own messages that I may have queued up */
892: PrintfQueue next = vascii->petsc_printfqueuebase, previous;
893: PetscInt i;
894: for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
895: PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
896: previous = next;
897: next = next->next;
898: PetscCall(PetscFree(previous->string));
899: PetscCall(PetscFree(previous));
900: }
901: vascii->petsc_printfqueue = NULL;
902: vascii->petsc_printfqueuelength = 0;
904: while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " "));
906: va_start(Argp, format);
907: PetscCall((*PetscVFPrintf)(fp, format, Argp));
908: PetscCall(PetscFFlush(fp));
909: if (petsc_history) {
910: va_start(Argp, format);
911: PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
912: PetscCall(PetscFFlush(petsc_history));
913: }
914: va_end(Argp);
915: } else { /* other processors add to queue */
916: char *string;
917: va_list Argp;
918: size_t fullLength;
919: PrintfQueue next;
921: PetscCall(PetscNew(&next));
922: if (vascii->petsc_printfqueue) {
923: vascii->petsc_printfqueue->next = next;
924: vascii->petsc_printfqueue = next;
925: } else {
926: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
927: }
928: vascii->petsc_printfqueuelength++;
929: next->size = QUEUESTRINGSIZE;
930: PetscCall(PetscCalloc1(next->size, &next->string));
931: string = next->string;
932: tab *= 2;
933: while (tab--) *string++ = ' ';
934: va_start(Argp, format);
935: PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
936: va_end(Argp);
937: if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
938: PetscCall(PetscFree(next->string));
939: next->size = fullLength + 2 * vascii->tab;
940: PetscCall(PetscCalloc1(next->size, &next->string));
941: string = next->string;
942: tab = 2 * vascii->tab;
943: while (tab--) *string++ = ' ';
944: va_start(Argp, format);
945: PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
946: va_end(Argp);
947: }
948: }
949: PetscFunctionReturn(PETSC_SUCCESS);
950: }
952: /*@C
953: PetscViewerASCIIRead - Reads from a ASCII file
955: Only process 0 in the `PetscViewer` may call this
957: Input Parameters:
958: + viewer - the `PETSCVIEWERASCII` viewer
959: . data - location to write the data
960: . num - number of items of data to read
961: - datatype - type of data to read
963: Output Parameters:
964: . count - number of items of data actually read, or `NULL`
966: Level: beginner
968: .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
969: `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
970: `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
971: @*/
972: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
973: {
974: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
975: FILE *fd = vascii->fd;
976: PetscInt i;
977: int ret = 0;
978: PetscMPIInt rank;
980: PetscFunctionBegin;
982: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
983: PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
984: for (i = 0; i < num; i++) {
985: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
986: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
987: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
988: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
989: else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
990: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
991: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
992: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
993: #if defined(PETSC_USE_REAL___FLOAT128)
994: else if (dtype == PETSC___FLOAT128) {
995: double tmp;
996: ret = fscanf(fd, "%lg", &tmp);
997: ((__float128 *)data)[i] = tmp;
998: }
999: #endif
1000: else
1001: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
1002: PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
1003: if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1004: }
1005: if (count) *count = i;
1006: else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
1007: PetscFunctionReturn(PETSC_SUCCESS);
1008: }