Actual source code: petscvu.c
petsc-3.7.7 2017-09-25
2: #include <petsc/private/viewerimpl.h> /*I "petscsys.h" I*/
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;
23: static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
24: {
25: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
29: if (vu->vecSeen) {
30: PetscViewerVUPrintDeferred(viewer, "};\n\n");
31: }
32: PetscViewerVUFlushDeferred(viewer);
33: PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
34: vu->fd = NULL;
35: PetscFree(vu->filename);
36: return(0);
37: }
41: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
42: {
43: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
47: PetscViewerFileClose_VU(viewer);
48: PetscFree(vu);
49: return(0);
50: }
54: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
55: {
56: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
57: PetscMPIInt rank;
58: int err;
62: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
63: if (!rank) {
64: err = fflush(vu->fd);
65: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
66: }
67: return(0);
68: }
72: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
73: {
74: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
77: *name = vu->filename;
78: return(0);
79: }
83: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
84: {
85: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
86: char fname[PETSC_MAX_PATH_LEN];
87: int rank;
91: if (!name) return(0);
92: PetscViewerFileClose_VU(viewer);
93: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
94: if (rank != 0) return(0);
95: PetscStrallocpy(name, &vu->filename);
96: PetscFixFilename(name, fname);
97: switch (vu->mode) {
98: case FILE_MODE_READ:
99: vu->fd = fopen(fname, "r");
100: break;
101: case FILE_MODE_WRITE:
102: vu->fd = fopen(fname, "w");
103: break;
104: case FILE_MODE_APPEND:
105: vu->fd = fopen(fname, "a");
106: break;
107: case FILE_MODE_UPDATE:
108: vu->fd = fopen(fname, "r+");
109: if (!vu->fd) vu->fd = fopen(fname, "w+");
110: break;
111: case FILE_MODE_APPEND_UPDATE:
112: /* I really want a file which is opened at the end for updating,
113: not a+, which opens at the beginning, but makes writes at the end.
114: */
115: vu->fd = fopen(fname, "r+");
116: if (!vu->fd) vu->fd = fopen(fname, "w+");
117: else {
118: fseek(vu->fd, 0, SEEK_END);
119: }
120: break;
121: default:
122: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
123: }
125: if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
126: #if defined(PETSC_USE_LOG)
127: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
128: #endif
129: return(0);
130: }
134: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
135: {
136: PetscViewer_VU *vu;
140: PetscNewLog(viewer,&vu);
141: viewer->data = (void*) vu;
143: viewer->ops->destroy = PetscViewerDestroy_VU;
144: viewer->ops->flush = PetscViewerFlush_VU;
145: viewer->ops->getsubviewer = NULL;
146: viewer->ops->restoresubviewer = NULL;
148: vu->fd = NULL;
149: vu->mode = FILE_MODE_WRITE;
150: vu->filename = NULL;
151: vu->vecSeen = PETSC_FALSE;
152: vu->queue = NULL;
153: vu->queueBase = NULL;
154: vu->queueLength = 0;
156: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
157: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
158: return(0);
159: }
163: /*@C
164: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
166: Not Collective
168: Input Parameter:
169: . viewer - The PetscViewer
171: Output Parameter:
172: . fd - The file pointer
174: Level: intermediate
176: Concepts: PetscViewer^file pointer
177: Concepts: file pointer^getting from PetscViewer
179: .seealso: PetscViewerASCIIGetPointer()
180: @*/
181: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
182: {
183: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
188: *fd = vu->fd;
189: return(0);
190: }
194: /*@C
195: PetscViewerVUSetMode - Sets the mode in which to open the file.
197: Not Collective
199: Input Parameters:
200: + viewer - The PetscViewer
201: - mode - The file mode
203: Level: intermediate
205: .keywords: Viewer, file, get, pointer
206: .seealso: PetscViewerASCIISetMode()
207: @*/
208: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
209: {
210: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
213: vu->mode = mode;
214: return(0);
215: }
219: /*@C
220: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
221: a vector. This is usually called internally rather than by a user.
223: Not Collective
225: Input Parameters:
226: + viewer - The PetscViewer
227: - vecSeen - The flag which indicates whether we have viewed a vector
229: Level: advanced
231: .keywords: Viewer, Vec
232: .seealso: PetscViewerVUGetVecSeen()
233: @*/
234: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
235: {
236: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
239: vu->vecSeen = vecSeen;
240: return(0);
241: }
245: /*@C
246: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
247: a vector. This is usually called internally rather than by a user.
249: Not Collective
251: Input Parameter:
252: . viewer - The PetscViewer
254: Output Parameter:
255: . vecSeen - The flag which indicates whether we have viewed a vector
257: Level: advanced
259: .keywords: Viewer, Vec
260: .seealso: PetscViewerVUGetVecSeen()
261: @*/
262: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
263: {
264: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
269: *vecSeen = vu->vecSeen;
270: return(0);
271: }
275: /*@C
276: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
278: Not Collective
280: Input Parameters:
281: + viewer - The PetscViewer
282: - format - The format string
284: Level: intermediate
286: .keywords: Viewer, print, deferred
287: .seealso: PetscViewerVUFlushDeferred()
288: @*/
289: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
290: {
291: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
292: va_list Argp;
293: size_t fullLength;
294: PrintfQueue next;
298: PetscNew(&next);
299: if (vu->queue) {
300: vu->queue->next = next;
301: vu->queue = next;
302: vu->queue->next = NULL;
303: } else {
304: vu->queueBase = vu->queue = next;
305: }
306: vu->queueLength++;
308: va_start(Argp, format);
309: PetscMemzero(next->string,QUEUESTRINGSIZE);
310: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
311: va_end(Argp);
312: return(0);
313: }
317: /*@C
318: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
320: Not Collective
322: Input Parameter:
323: + viewer - The PetscViewer
325: Level: intermediate
327: .keywords: Viewer, flush, deferred
328: .seealso: PetscViewerVUPrintDeferred()
329: @*/
330: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
331: {
332: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
333: PrintfQueue next = vu->queueBase;
334: PrintfQueue previous;
335: int i;
339: for (i = 0; i < vu->queueLength; i++) {
340: PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
341: previous = next;
342: next = next->next;
343: PetscFree(previous);
344: }
345: vu->queue = NULL;
346: vu->queueLength = 0;
347: return(0);
348: }