Actual source code: petscvu.c
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;
25: if (vu->vecSeen) {
26: PetscViewerVUPrintDeferred(viewer, "};\n\n");
27: }
28: PetscViewerVUFlushDeferred(viewer);
29: PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
30: vu->fd = NULL;
31: PetscFree(vu->filename);
32: return 0;
33: }
35: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
36: {
37: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
39: PetscViewerFileClose_VU(viewer);
40: PetscFree(vu);
41: return 0;
42: }
44: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
45: {
46: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
47: PetscMPIInt rank;
48: int err;
50: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
51: if (rank == 0) {
52: err = fflush(vu->fd);
54: }
55: return 0;
56: }
58: static PetscErrorCode PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode)
59: {
60: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
62: vu->mode = mode;
63: return 0;
64: }
66: static PetscErrorCode PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type)
67: {
68: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
70: *type = vu->mode;
71: return 0;
72: }
74: static PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
75: {
76: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
78: *name = vu->filename;
79: return 0;
80: }
82: static PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
83: {
84: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
85: char fname[PETSC_MAX_PATH_LEN];
86: int rank;
88: if (!name) return 0;
89: PetscViewerFileClose_VU(viewer);
90: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
91: if (rank != 0) return 0;
92: PetscStrallocpy(name, &vu->filename);
93: PetscFixFilename(name, fname);
94: switch (vu->mode) {
95: case FILE_MODE_READ:
96: vu->fd = fopen(fname, "r");
97: break;
98: case FILE_MODE_WRITE:
99: vu->fd = fopen(fname, "w");
100: break;
101: case FILE_MODE_APPEND:
102: vu->fd = fopen(fname, "a");
103: break;
104: case FILE_MODE_UPDATE:
105: vu->fd = fopen(fname, "r+");
106: if (!vu->fd) vu->fd = fopen(fname, "w+");
107: break;
108: case FILE_MODE_APPEND_UPDATE:
109: /* I really want a file which is opened at the end for updating,
110: not a+, which opens at the beginning, but makes writes at the end.
111: */
112: vu->fd = fopen(fname, "r+");
113: if (!vu->fd) vu->fd = fopen(fname, "w+");
114: else {
115: fseek(vu->fd, 0, SEEK_END);
116: }
117: break;
118: default:
119: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP, "Unsupported file mode %s",PetscFileModes[vu->mode]);
120: }
123: #if defined(PETSC_USE_LOG)
124: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
125: #endif
126: return 0;
127: }
129: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
130: {
131: PetscViewer_VU *vu;
133: PetscNewLog(viewer,&vu);
134: viewer->data = (void*) vu;
136: viewer->ops->destroy = PetscViewerDestroy_VU;
137: viewer->ops->flush = PetscViewerFlush_VU;
138: viewer->ops->getsubviewer = NULL;
139: viewer->ops->restoresubviewer = NULL;
141: vu->fd = NULL;
142: vu->mode = FILE_MODE_WRITE;
143: vu->filename = NULL;
144: vu->vecSeen = PETSC_FALSE;
145: vu->queue = NULL;
146: vu->queueBase = NULL;
147: vu->queueLength = 0;
149: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
150: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
151: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VU);
152: PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_VU);
153: return 0;
154: }
156: /*@C
157: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
159: Not Collective
161: Input Parameter:
162: . viewer - The PetscViewer
164: Output Parameter:
165: . fd - The file pointer
167: Level: intermediate
169: .seealso: PetscViewerASCIIGetPointer()
170: @*/
171: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
172: {
173: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
177: *fd = vu->fd;
178: return 0;
179: }
181: /*@C
182: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
183: a vector. This is usually called internally rather than by a user.
185: Not Collective
187: Input Parameters:
188: + viewer - The PetscViewer
189: - vecSeen - The flag which indicates whether we have viewed a vector
191: Level: advanced
193: .seealso: PetscViewerVUGetVecSeen()
194: @*/
195: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
196: {
197: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
199: vu->vecSeen = vecSeen;
200: return 0;
201: }
203: /*@C
204: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
205: a vector. This is usually called internally rather than by a user.
207: Not Collective
209: Input Parameter:
210: . viewer - The PetscViewer
212: Output Parameter:
213: . vecSeen - The flag which indicates whether we have viewed a vector
215: Level: advanced
217: .seealso: PetscViewerVUGetVecSeen()
218: @*/
219: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
220: {
221: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
225: *vecSeen = vu->vecSeen;
226: return 0;
227: }
229: /*@C
230: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
232: Not Collective
234: Input Parameters:
235: + viewer - The PetscViewer
236: - format - The format string
238: Level: intermediate
240: .seealso: PetscViewerVUFlushDeferred()
241: @*/
242: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
243: {
244: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
245: va_list Argp;
246: size_t fullLength;
247: PrintfQueue next;
249: PetscNew(&next);
250: if (vu->queue) {
251: vu->queue->next = next;
252: vu->queue = next;
253: vu->queue->next = NULL;
254: } else {
255: vu->queueBase = vu->queue = next;
256: }
257: vu->queueLength++;
259: va_start(Argp, format);
260: PetscArrayzero(next->string,QUEUESTRINGSIZE);
261: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
262: va_end(Argp);
263: return 0;
264: }
266: /*@C
267: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
269: Not Collective
271: Input Parameter:
272: . viewer - The PetscViewer
274: Level: intermediate
276: .seealso: PetscViewerVUPrintDeferred()
277: @*/
278: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
279: {
280: PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
281: PrintfQueue next = vu->queueBase;
282: PrintfQueue previous;
283: int i;
285: for (i = 0; i < vu->queueLength; i++) {
286: PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
287: previous = next;
288: next = next->next;
289: PetscFree(previous);
290: }
291: vu->queue = NULL;
292: vu->queueLength = 0;
293: return 0;
294: }