Actual source code: petscvu.c
2: #include src/sys/src/viewer/viewerimpl.h
3: #include <stdarg.h>
4: #include "petscfix.h"
6: #define QUEUESTRINGSIZE 1024
8: typedef struct _PrintfQueue *PrintfQueue;
9: struct _PrintfQueue {
10: char string[QUEUESTRINGSIZE];
11: PrintfQueue next;
12: };
14: typedef struct {
15: FILE *fd;
16: PetscFileMode mode; /* The mode in which to open the file */
17: char *filename;
18: PetscTruth vecSeen; /* The flag indicating whether any vector has been viewed so far */
19: PrintfQueue queue, queueBase;
20: int queueLength;
21: } PetscViewer_VU;
25: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
26: {
27: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
31: if (vu->vecSeen == PETSC_TRUE) {
32: PetscViewerVUPrintDeferred(viewer, "};\n\n");
33: }
34: PetscViewerVUFlushDeferred(viewer);
35: PetscFClose(viewer->comm, vu->fd);
36: PetscStrfree(vu->filename);
37: PetscFree(vu);
38: return(0);
39: }
43: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
44: {
45: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
46: int rank;
50: MPI_Comm_rank(viewer->comm, &rank);
51: if (!rank) fflush(vu->fd);
52: return(0);
53: }
58: PetscErrorCode PetscViewerGetFilename_VU(PetscViewer viewer, char **name)
59: {
60: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
63: *name = vu->filename;
64: return(0);
65: }
71: PetscErrorCode PetscViewerSetFilename_VU(PetscViewer viewer, const char name[])
72: {
73: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
74: char fname[PETSC_MAX_PATH_LEN];
75: int rank;
79: if (!name) return(0);
80: MPI_Comm_rank(viewer->comm, &rank);
81: if (rank != 0) return(0);
82: PetscStrallocpy(name, &vu->filename);
83: PetscFixFilename(name, fname);
84: switch(vu->mode) {
85: case FILE_MODE_READ:
86: vu->fd = fopen(fname, "r");
87: break;
88: case FILE_MODE_WRITE:
89: vu->fd = fopen(fname, "w");
90: break;
91: case FILE_MODE_APPEND:
92: vu->fd = fopen(fname, "a");
93: break;
94: case FILE_MODE_UPDATE:
95: vu->fd = fopen(fname, "r+");
96: if (!vu->fd) {
97: vu->fd = fopen(fname, "w+");
98: }
99: break;
100: case FILE_MODE_APPEND_UPDATE:
101: /* I really want a file which is opened at the end for updating,
102: not a+, which opens at the beginning, but makes writes at the end.
103: */
104: vu->fd = fopen(fname, "r+");
105: if (!vu->fd) {
106: vu->fd = fopen(fname, "w+");
107: } else {
108: fseek(vu->fd, 0, SEEK_END);
109: }
110: break;
111: default:
112: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
113: }
115: if (!vu->fd) SETERRQ1(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
120: return(0);
121: }
127: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
128: {
129: PetscViewer_VU *vu;
133: PetscNew(PetscViewer_VU, &vu);
134: viewer->data = (void*) vu;
136: viewer->ops->destroy = PetscViewerDestroy_VU;
137: viewer->ops->flush = PetscViewerFlush_VU;
138: viewer->ops->getsingleton = PETSC_NULL;
139: viewer->ops->restoresingleton = PETSC_NULL;
140: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
141: viewer->iformat = 0;
143: vu->fd = PETSC_NULL;
144: vu->mode = FILE_MODE_WRITE;
145: vu->filename = PETSC_NULL;
146: vu->vecSeen = PETSC_FALSE;
147: vu->queue = PETSC_NULL;
148: vu->queueBase = PETSC_NULL;
149: vu->queueLength = 0;
151: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerSetFilename_C", "PetscViewerSetFilename_VU",
152: PetscViewerSetFilename_VU);
153: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerGetFilename_C", "PetscViewerGetFilename_VU",
154: PetscViewerGetFilename_VU);
156: return(0);
157: }
162: /*@C
163: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
165: Not Collective
167: Input Parameter:
168: . viewer - The PetscViewer
170: Output Parameter:
171: . fd - The file pointer
173: Level: intermediate
175: Concepts: PetscViewer^file pointer
176: Concepts: file pointer^getting from PetscViewer
178: .seealso: PetscViewerASCIIGetPointer()
179: @*/
180: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
181: {
182: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
187: *fd = vu->fd;
188: return(0);
189: }
193: /*@C
194: PetscViewerVUSetMode - Sets the mode in which to open the file.
196: Not Collective
198: Input Parameters:
199: + viewer - The PetscViewer
200: - mode - The file mode
202: Level: intermediate
204: .keywords: Viewer, file, get, pointer
205: .seealso: PetscViewerASCIISetMode()
206: @*/
207: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
208: {
209: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
212: vu->mode = mode;
213: return(0);
214: }
218: /*@C
219: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
220: a vector. This is usually called internally rather than by a user.
222: Not Collective
224: Input Parameters:
225: + viewer - The PetscViewer
226: - vecSeen - The flag which indicates whether we have viewed a vector
228: Level: advanced
230: .keywords: Viewer, Vec
231: .seealso: PetscViewerVUGetVecSeen()
232: @*/
233: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
234: {
235: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
238: vu->vecSeen = vecSeen;
239: return(0);
240: }
244: /*@C
245: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
246: a vector. This is usually called internally rather than by a user.
248: Not Collective
250: Input Parameter:
251: . viewer - The PetscViewer
253: Output Parameter:
254: . vecSeen - The flag which indicates whether we have viewed a vector
256: Level: advanced
258: .keywords: Viewer, Vec
259: .seealso: PetscViewerVUGetVecSeen()
260: @*/
261: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
262: {
263: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
268: *vecSeen = vu->vecSeen;
269: return(0);
270: }
274: /*@C
275: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
277: Not Collective
279: Input Parameters:
280: + viewer - The PetscViewer
281: - format - The format string
283: Level: intermediate
285: .keywords: Viewer, print, deferred
286: .seealso: PetscViewerVUFlushDeferred()
287: @*/
288: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
289: {
290: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
291: va_list Argp;
292: PrintfQueue next;
296: PetscNew(struct _PrintfQueue, &next);
297: if (vu->queue != PETSC_NULL) {
298: vu->queue->next = next;
299: vu->queue = next;
300: vu->queue->next = PETSC_NULL;
301: } else {
302: vu->queueBase = vu->queue = next;
303: }
304: vu->queueLength++;
306: va_start(Argp, format);
307: PetscMemzero(next->string,QUEUESTRINGSIZE);
308: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format, Argp);
309: va_end(Argp);
310: return(0);
311: }
315: /*@C
316: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
318: Not Collective
320: Input Parameter:
321: + viewer - The PetscViewer
323: Level: intermediate
325: .keywords: Viewer, flush, deferred
326: .seealso: PetscViewerVUPrintDeferred()
327: @*/
328: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
329: {
330: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
331: PrintfQueue next = vu->queueBase;
332: PrintfQueue previous;
333: int i;
337: for(i = 0; i < vu->queueLength; i++) {
338: PetscFPrintf(viewer->comm, vu->fd, "%s", next->string);
339: previous = next;
340: next = next->next;
341: PetscFree(previous);
342: }
343: vu->queue = PETSC_NULL;
344: vu->queueLength = 0;
345: return(0);
346: }