Actual source code: petscvu.c
petsc-3.11.4 2019-09-28
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
162: Concepts: PetscViewer^file pointer
163: Concepts: file pointer^getting from PetscViewer
165: .seealso: PetscViewerASCIIGetPointer()
166: @*/
167: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
168: {
169: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
174: *fd = vu->fd;
175: return(0);
176: }
178: /*@C
179: PetscViewerVUSetMode - Sets the mode in which to open the file.
181: Not Collective
183: Input Parameters:
184: + viewer - The PetscViewer
185: - mode - The file mode
187: Level: intermediate
189: .keywords: Viewer, file, get, pointer
190: .seealso: PetscViewerASCIISetMode()
191: @*/
192: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
193: {
194: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
197: vu->mode = mode;
198: return(0);
199: }
201: /*@C
202: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
203: a vector. This is usually called internally rather than by a user.
205: Not Collective
207: Input Parameters:
208: + viewer - The PetscViewer
209: - vecSeen - The flag which indicates whether we have viewed a vector
211: Level: advanced
213: .keywords: Viewer, Vec
214: .seealso: PetscViewerVUGetVecSeen()
215: @*/
216: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
217: {
218: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
221: vu->vecSeen = vecSeen;
222: return(0);
223: }
225: /*@C
226: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
227: a vector. This is usually called internally rather than by a user.
229: Not Collective
231: Input Parameter:
232: . viewer - The PetscViewer
234: Output Parameter:
235: . vecSeen - The flag which indicates whether we have viewed a vector
237: Level: advanced
239: .keywords: Viewer, Vec
240: .seealso: PetscViewerVUGetVecSeen()
241: @*/
242: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
243: {
244: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
249: *vecSeen = vu->vecSeen;
250: return(0);
251: }
253: /*@C
254: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
256: Not Collective
258: Input Parameters:
259: + viewer - The PetscViewer
260: - format - The format string
262: Level: intermediate
264: .keywords: Viewer, print, deferred
265: .seealso: PetscViewerVUFlushDeferred()
266: @*/
267: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
268: {
269: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
270: va_list Argp;
271: size_t fullLength;
272: PrintfQueue next;
276: PetscNew(&next);
277: if (vu->queue) {
278: vu->queue->next = next;
279: vu->queue = next;
280: vu->queue->next = NULL;
281: } else {
282: vu->queueBase = vu->queue = next;
283: }
284: vu->queueLength++;
286: va_start(Argp, format);
287: PetscMemzero(next->string,QUEUESTRINGSIZE);
288: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
289: va_end(Argp);
290: return(0);
291: }
293: /*@C
294: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
296: Not Collective
298: Input Parameter:
299: + viewer - The PetscViewer
301: Level: intermediate
303: .keywords: Viewer, flush, deferred
304: .seealso: PetscViewerVUPrintDeferred()
305: @*/
306: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
307: {
308: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
309: PrintfQueue next = vu->queueBase;
310: PrintfQueue previous;
311: int i;
315: for (i = 0; i < vu->queueLength; i++) {
316: PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
317: previous = next;
318: next = next->next;
319: PetscFree(previous);
320: }
321: vu->queue = NULL;
322: vu->queueLength = 0;
323: return(0);
324: }