Actual source code: petscvu.c
petsc-3.13.6 2020-09-29
2: #include <petsc/private/viewerimpl.h>
4: #define QUEUESTRINGSIZE 1024
6: typedef struct _PrintfQueue *PrintfQueue;
7: struct _PrintfQueue {
8: char string[QUEUESTRINGSIZE];
9: PrintfQueue next;
10: };
12: typedef struct {
13: FILE *fd;
14: PetscFileMode mode; /* The mode in which to open the file */
15: char *filename;
16: PetscBool vecSeen; /* The flag indicating whether any vector has been viewed so far */
17: PrintfQueue queue, queueBase;
18: int queueLength;
19: } PetscViewer_VU;
21: static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
22: {
23: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
27: if (vu->vecSeen) {
28: PetscViewerVUPrintDeferred(viewer, "};\n\n");
29: }
30: PetscViewerVUFlushDeferred(viewer);
31: PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
32: vu->fd = NULL;
33: PetscFree(vu->filename);
34: return(0);
35: }
37: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
38: {
39: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
43: PetscViewerFileClose_VU(viewer);
44: PetscFree(vu);
45: return(0);
46: }
48: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
49: {
50: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
51: PetscMPIInt rank;
52: int err;
56: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
57: if (!rank) {
58: err = fflush(vu->fd);
59: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
60: }
61: return(0);
62: }
64: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
65: {
66: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
69: *name = vu->filename;
70: return(0);
71: }
73: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
74: {
75: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
76: char fname[PETSC_MAX_PATH_LEN];
77: int rank;
81: if (!name) return(0);
82: PetscViewerFileClose_VU(viewer);
83: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
84: if (rank != 0) return(0);
85: PetscStrallocpy(name, &vu->filename);
86: PetscFixFilename(name, fname);
87: switch (vu->mode) {
88: case FILE_MODE_READ:
89: vu->fd = fopen(fname, "r");
90: break;
91: case FILE_MODE_WRITE:
92: vu->fd = fopen(fname, "w");
93: break;
94: case FILE_MODE_APPEND:
95: vu->fd = fopen(fname, "a");
96: break;
97: case FILE_MODE_UPDATE:
98: vu->fd = fopen(fname, "r+");
99: if (!vu->fd) vu->fd = fopen(fname, "w+");
100: break;
101: case FILE_MODE_APPEND_UPDATE:
102: /* I really want a file which is opened at the end for updating,
103: not a+, which opens at the beginning, but makes writes at the end.
104: */
105: vu->fd = fopen(fname, "r+");
106: if (!vu->fd) vu->fd = fopen(fname, "w+");
107: else {
108: fseek(vu->fd, 0, SEEK_END);
109: }
110: break;
111: default:
112: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
113: }
115: if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
116: #if defined(PETSC_USE_LOG)
117: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
118: #endif
119: return(0);
120: }
122: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
123: {
124: PetscViewer_VU *vu;
128: PetscNewLog(viewer,&vu);
129: viewer->data = (void*) vu;
131: viewer->ops->destroy = PetscViewerDestroy_VU;
132: viewer->ops->flush = PetscViewerFlush_VU;
133: viewer->ops->getsubviewer = NULL;
134: viewer->ops->restoresubviewer = NULL;
136: vu->fd = NULL;
137: vu->mode = FILE_MODE_WRITE;
138: vu->filename = NULL;
139: vu->vecSeen = PETSC_FALSE;
140: vu->queue = NULL;
141: vu->queueBase = NULL;
142: vu->queueLength = 0;
144: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
145: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
146: return(0);
147: }
149: /*@C
150: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
152: Not Collective
154: Input Parameter:
155: . viewer - The PetscViewer
157: Output Parameter:
158: . fd - The file pointer
160: Level: intermediate
163: .seealso: PetscViewerASCIIGetPointer()
164: @*/
165: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
166: {
167: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
172: *fd = vu->fd;
173: return(0);
174: }
176: /*@C
177: PetscViewerVUSetMode - Sets the mode in which to open the file.
179: Not Collective
181: Input Parameters:
182: + viewer - The PetscViewer
183: - mode - The file mode
185: Level: intermediate
187: .seealso: PetscViewerASCIISetMode()
188: @*/
189: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
190: {
191: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
194: vu->mode = mode;
195: return(0);
196: }
198: /*@C
199: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
200: a vector. This is usually called internally rather than by a user.
202: Not Collective
204: Input Parameters:
205: + viewer - The PetscViewer
206: - vecSeen - The flag which indicates whether we have viewed a vector
208: Level: advanced
210: .seealso: PetscViewerVUGetVecSeen()
211: @*/
212: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
213: {
214: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
217: vu->vecSeen = vecSeen;
218: return(0);
219: }
221: /*@C
222: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
223: a vector. This is usually called internally rather than by a user.
225: Not Collective
227: Input Parameter:
228: . viewer - The PetscViewer
230: Output Parameter:
231: . vecSeen - The flag which indicates whether we have viewed a vector
233: Level: advanced
235: .seealso: PetscViewerVUGetVecSeen()
236: @*/
237: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
238: {
239: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
244: *vecSeen = vu->vecSeen;
245: return(0);
246: }
248: /*@C
249: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
251: Not Collective
253: Input Parameters:
254: + viewer - The PetscViewer
255: - format - The format string
257: Level: intermediate
259: .seealso: PetscViewerVUFlushDeferred()
260: @*/
261: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
262: {
263: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
264: va_list Argp;
265: size_t fullLength;
266: PrintfQueue next;
270: PetscNew(&next);
271: if (vu->queue) {
272: vu->queue->next = next;
273: vu->queue = next;
274: vu->queue->next = NULL;
275: } else {
276: vu->queueBase = vu->queue = next;
277: }
278: vu->queueLength++;
280: va_start(Argp, format);
281: PetscArrayzero(next->string,QUEUESTRINGSIZE);
282: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
283: va_end(Argp);
284: return(0);
285: }
287: /*@C
288: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
290: Not Collective
292: Input Parameter:
293: . viewer - The PetscViewer
295: Level: intermediate
297: .seealso: PetscViewerVUPrintDeferred()
298: @*/
299: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
300: {
301: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
302: PrintfQueue next = vu->queueBase;
303: PrintfQueue previous;
304: int i;
308: for (i = 0; i < vu->queueLength; i++) {
309: PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
310: previous = next;
311: next = next->next;
312: PetscFree(previous);
313: }
314: vu->queue = NULL;
315: vu->queueLength = 0;
316: return(0);
317: }