Actual source code: petscvu.c
2: #include <private/viewerimpl.h> /*I "petscsys.h" I*/
3: #include <stdarg.h>
5: #define QUEUESTRINGSIZE 1024
7: typedef struct _PrintfQueue *PrintfQueue;
8: struct _PrintfQueue {
9: char string[QUEUESTRINGSIZE];
10: PrintfQueue next;
11: };
13: typedef struct {
14: FILE *fd;
15: PetscFileMode mode; /* The mode in which to open the file */
16: char *filename;
17: PetscBool vecSeen; /* The flag indicating whether any vector has been viewed so far */
18: PrintfQueue queue, queueBase;
19: int queueLength;
20: } PetscViewer_VU;
24: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
25: {
26: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
30: if (vu->vecSeen) {
31: PetscViewerVUPrintDeferred(viewer, "};\n\n");
32: }
33: PetscViewerVUFlushDeferred(viewer);
34: PetscFClose(((PetscObject)viewer)->comm, vu->fd);
35: PetscFree(vu->filename);
36: PetscFree(vu);
37: return(0);
38: }
42: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
43: {
44: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
45: PetscMPIInt rank;
46: int err;
50: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
51: if (!rank) {
52: err = fflush(vu->fd);
53: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
54: }
55: return(0);
56: }
61: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
62: {
63: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
66: *name = vu->filename;
67: return(0);
68: }
74: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
75: {
76: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
77: char fname[PETSC_MAX_PATH_LEN];
78: int rank;
82: if (!name) return(0);
83: MPI_Comm_rank(((PetscObject)viewer)->comm, &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) {
100: vu->fd = fopen(fname, "w+");
101: }
102: break;
103: case FILE_MODE_APPEND_UPDATE:
104: /* I really want a file which is opened at the end for updating,
105: not a+, which opens at the beginning, but makes writes at the end.
106: */
107: vu->fd = fopen(fname, "r+");
108: if (!vu->fd) {
109: vu->fd = fopen(fname, "w+");
110: } else {
111: fseek(vu->fd, 0, SEEK_END);
112: }
113: break;
114: default:
115: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
116: }
118: if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
119: #if defined(PETSC_USE_LOG)
120: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
121: #endif
123: return(0);
124: }
130: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
131: {
132: PetscViewer_VU *vu;
136: PetscNewLog(viewer,PetscViewer_VU, &vu);
137: viewer->data = (void*) vu;
139: viewer->ops->destroy = PetscViewerDestroy_VU;
140: viewer->ops->flush = PetscViewerFlush_VU;
141: viewer->ops->getsingleton = PETSC_NULL;
142: viewer->ops->restoresingleton = PETSC_NULL;
143: viewer->format = PETSC_VIEWER_DEFAULT;
144: viewer->iformat = 0;
146: vu->fd = PETSC_NULL;
147: vu->mode = FILE_MODE_WRITE;
148: vu->filename = PETSC_NULL;
149: vu->vecSeen = PETSC_FALSE;
150: vu->queue = PETSC_NULL;
151: vu->queueBase = PETSC_NULL;
152: vu->queueLength = 0;
154: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
155: PetscViewerFileSetName_VU);
156: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
157: PetscViewerFileGetName_VU);
159: return(0);
160: }
165: /*@C
166: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
168: Not Collective
170: Input Parameter:
171: . viewer - The PetscViewer
173: Output Parameter:
174: . fd - The file pointer
176: Level: intermediate
178: Concepts: PetscViewer^file pointer
179: Concepts: file pointer^getting from PetscViewer
181: .seealso: PetscViewerASCIIGetPointer()
182: @*/
183: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
184: {
185: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
190: *fd = vu->fd;
191: return(0);
192: }
196: /*@C
197: PetscViewerVUSetMode - Sets the mode in which to open the file.
199: Not Collective
201: Input Parameters:
202: + viewer - The PetscViewer
203: - mode - The file mode
205: Level: intermediate
207: .keywords: Viewer, file, get, pointer
208: .seealso: PetscViewerASCIISetMode()
209: @*/
210: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
211: {
212: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
215: vu->mode = mode;
216: return(0);
217: }
221: /*@C
222: PetscViewerVUSetVecSeen - Sets 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 Parameters:
228: + viewer - The PetscViewer
229: - vecSeen - The flag which indicates whether we have viewed a vector
231: Level: advanced
233: .keywords: Viewer, Vec
234: .seealso: PetscViewerVUGetVecSeen()
235: @*/
236: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
237: {
238: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
241: vu->vecSeen = vecSeen;
242: return(0);
243: }
247: /*@C
248: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
249: a vector. This is usually called internally rather than by a user.
251: Not Collective
253: Input Parameter:
254: . viewer - The PetscViewer
256: Output Parameter:
257: . vecSeen - The flag which indicates whether we have viewed a vector
259: Level: advanced
261: .keywords: Viewer, Vec
262: .seealso: PetscViewerVUGetVecSeen()
263: @*/
264: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
265: {
266: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
271: *vecSeen = vu->vecSeen;
272: return(0);
273: }
277: /*@C
278: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
280: Not Collective
282: Input Parameters:
283: + viewer - The PetscViewer
284: - format - The format string
286: Level: intermediate
288: .keywords: Viewer, print, deferred
289: .seealso: PetscViewerVUFlushDeferred()
290: @*/
291: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
292: {
293: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
294: va_list Argp;
295: size_t fullLength;
296: PrintfQueue next;
300: PetscNew(struct _PrintfQueue, &next);
301: if (vu->queue) {
302: vu->queue->next = next;
303: vu->queue = next;
304: vu->queue->next = PETSC_NULL;
305: } else {
306: vu->queueBase = vu->queue = next;
307: }
308: vu->queueLength++;
310: va_start(Argp, format);
311: PetscMemzero(next->string,QUEUESTRINGSIZE);
312: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
313: va_end(Argp);
314: return(0);
315: }
319: /*@C
320: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
322: Not Collective
324: Input Parameter:
325: + viewer - The PetscViewer
327: Level: intermediate
329: .keywords: Viewer, flush, deferred
330: .seealso: PetscViewerVUPrintDeferred()
331: @*/
332: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
333: {
334: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
335: PrintfQueue next = vu->queueBase;
336: PrintfQueue previous;
337: int i;
341: for(i = 0; i < vu->queueLength; i++) {
342: PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
343: previous = next;
344: next = next->next;
345: PetscFree(previous);
346: }
347: vu->queue = PETSC_NULL;
348: vu->queueLength = 0;
349: return(0);
350: }