Actual source code: petscvu.c
petsc-3.3-p7 2013-05-11
2: #include <petsc-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: static PetscErrorCode PetscViewerFileClose_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: vu->fd = PETSC_NULL;
36: PetscFree(vu->filename);
37: return(0);
38: }
42: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
43: {
44: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
48: PetscViewerFileClose_VU(viewer);
49: PetscFree(vu);
50: return(0);
51: }
55: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
56: {
57: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
58: PetscMPIInt rank;
59: int err;
63: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
64: if (!rank) {
65: err = fflush(vu->fd);
66: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
67: }
68: return(0);
69: }
71: EXTERN_C_BEGIN
74: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
75: {
76: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
79: *name = vu->filename;
80: return(0);
81: }
82: EXTERN_C_END
84: EXTERN_C_BEGIN
87: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
88: {
89: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
90: char fname[PETSC_MAX_PATH_LEN];
91: int rank;
95: if (!name) return(0);
96: PetscViewerFileClose_VU(viewer);
97: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
98: if (rank != 0) return(0);
99: PetscStrallocpy(name, &vu->filename);
100: PetscFixFilename(name, fname);
101: switch(vu->mode) {
102: case FILE_MODE_READ:
103: vu->fd = fopen(fname, "r");
104: break;
105: case FILE_MODE_WRITE:
106: vu->fd = fopen(fname, "w");
107: break;
108: case FILE_MODE_APPEND:
109: vu->fd = fopen(fname, "a");
110: break;
111: case FILE_MODE_UPDATE:
112: vu->fd = fopen(fname, "r+");
113: if (!vu->fd) {
114: vu->fd = fopen(fname, "w+");
115: }
116: break;
117: case FILE_MODE_APPEND_UPDATE:
118: /* I really want a file which is opened at the end for updating,
119: not a+, which opens at the beginning, but makes writes at the end.
120: */
121: vu->fd = fopen(fname, "r+");
122: if (!vu->fd) {
123: vu->fd = fopen(fname, "w+");
124: } else {
125: fseek(vu->fd, 0, SEEK_END);
126: }
127: break;
128: default:
129: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
130: }
132: if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
133: #if defined(PETSC_USE_LOG)
134: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
135: #endif
137: return(0);
138: }
139: EXTERN_C_END
141: EXTERN_C_BEGIN
144: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
145: {
146: PetscViewer_VU *vu;
150: PetscNewLog(viewer,PetscViewer_VU, &vu);
151: viewer->data = (void*) vu;
153: viewer->ops->destroy = PetscViewerDestroy_VU;
154: viewer->ops->flush = PetscViewerFlush_VU;
155: viewer->ops->getsingleton = PETSC_NULL;
156: viewer->ops->restoresingleton = PETSC_NULL;
157: viewer->format = PETSC_VIEWER_DEFAULT;
158: viewer->iformat = 0;
160: vu->fd = PETSC_NULL;
161: vu->mode = FILE_MODE_WRITE;
162: vu->filename = PETSC_NULL;
163: vu->vecSeen = PETSC_FALSE;
164: vu->queue = PETSC_NULL;
165: vu->queueBase = PETSC_NULL;
166: vu->queueLength = 0;
168: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
169: PetscViewerFileSetName_VU);
170: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
171: PetscViewerFileGetName_VU);
173: return(0);
174: }
175: EXTERN_C_END
179: /*@C
180: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
182: Not Collective
184: Input Parameter:
185: . viewer - The PetscViewer
187: Output Parameter:
188: . fd - The file pointer
190: Level: intermediate
192: Concepts: PetscViewer^file pointer
193: Concepts: file pointer^getting from PetscViewer
195: .seealso: PetscViewerASCIIGetPointer()
196: @*/
197: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
198: {
199: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
204: *fd = vu->fd;
205: return(0);
206: }
210: /*@C
211: PetscViewerVUSetMode - Sets the mode in which to open the file.
213: Not Collective
215: Input Parameters:
216: + viewer - The PetscViewer
217: - mode - The file mode
219: Level: intermediate
221: .keywords: Viewer, file, get, pointer
222: .seealso: PetscViewerASCIISetMode()
223: @*/
224: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
225: {
226: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
229: vu->mode = mode;
230: return(0);
231: }
235: /*@C
236: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
237: a vector. This is usually called internally rather than by a user.
239: Not Collective
241: Input Parameters:
242: + viewer - The PetscViewer
243: - vecSeen - The flag which indicates whether we have viewed a vector
245: Level: advanced
247: .keywords: Viewer, Vec
248: .seealso: PetscViewerVUGetVecSeen()
249: @*/
250: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
251: {
252: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
255: vu->vecSeen = vecSeen;
256: return(0);
257: }
261: /*@C
262: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
263: a vector. This is usually called internally rather than by a user.
265: Not Collective
267: Input Parameter:
268: . viewer - The PetscViewer
270: Output Parameter:
271: . vecSeen - The flag which indicates whether we have viewed a vector
273: Level: advanced
275: .keywords: Viewer, Vec
276: .seealso: PetscViewerVUGetVecSeen()
277: @*/
278: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
279: {
280: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
285: *vecSeen = vu->vecSeen;
286: return(0);
287: }
291: /*@C
292: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
294: Not Collective
296: Input Parameters:
297: + viewer - The PetscViewer
298: - format - The format string
300: Level: intermediate
302: .keywords: Viewer, print, deferred
303: .seealso: PetscViewerVUFlushDeferred()
304: @*/
305: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
306: {
307: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
308: va_list Argp;
309: size_t fullLength;
310: PrintfQueue next;
314: PetscNew(struct _PrintfQueue, &next);
315: if (vu->queue) {
316: vu->queue->next = next;
317: vu->queue = next;
318: vu->queue->next = PETSC_NULL;
319: } else {
320: vu->queueBase = vu->queue = next;
321: }
322: vu->queueLength++;
324: va_start(Argp, format);
325: PetscMemzero(next->string,QUEUESTRINGSIZE);
326: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
327: va_end(Argp);
328: return(0);
329: }
333: /*@C
334: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
336: Not Collective
338: Input Parameter:
339: + viewer - The PetscViewer
341: Level: intermediate
343: .keywords: Viewer, flush, deferred
344: .seealso: PetscViewerVUPrintDeferred()
345: @*/
346: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
347: {
348: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
349: PrintfQueue next = vu->queueBase;
350: PrintfQueue previous;
351: int i;
355: for(i = 0; i < vu->queueLength; i++) {
356: PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
357: previous = next;
358: next = next->next;
359: PetscFree(previous);
360: }
361: vu->queue = PETSC_NULL;
362: vu->queueLength = 0;
363: return(0);
364: }