xref: /petsc/src/sys/classes/viewer/impls/vu/petscvu.c (revision 2205254efee3a00a594e5e2a3a70f74dcb40bc03)
1 
2 #include <petsc-private/viewerimpl.h>  /*I     "petscsys.h"   I*/
3 #include <stdarg.h>
4 
5 #define QUEUESTRINGSIZE 1024
6 
7 typedef struct _PrintfQueue *PrintfQueue;
8 struct _PrintfQueue {
9   char        string[QUEUESTRINGSIZE];
10   PrintfQueue next;
11 };
12 
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;
21 
22 #undef __FUNCT__
23 #define __FUNCT__ "PetscViewerFileClose_VU"
24 static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
25 {
26   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
27   PetscErrorCode ierr;
28 
29   PetscFunctionBegin;
30   if (vu->vecSeen) {
31     ierr = PetscViewerVUPrintDeferred(viewer, "};\n\n");CHKERRQ(ierr);
32   }
33   ierr   = PetscViewerVUFlushDeferred(viewer);CHKERRQ(ierr);
34   ierr   = PetscFClose(((PetscObject)viewer)->comm, vu->fd);CHKERRQ(ierr);
35   vu->fd = PETSC_NULL;
36   ierr   = PetscFree(vu->filename);CHKERRQ(ierr);
37   PetscFunctionReturn(0);
38 }
39 
40 #undef __FUNCT__
41 #define __FUNCT__ "PetscViewerDestroy_VU"
42 PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
43 {
44   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
45   PetscErrorCode ierr;
46 
47   PetscFunctionBegin;
48   ierr = PetscViewerFileClose_VU(viewer);CHKERRQ(ierr);
49   ierr = PetscFree(vu);CHKERRQ(ierr);
50   PetscFunctionReturn(0);
51 }
52 
53 #undef __FUNCT__
54 #define __FUNCT__ "PetscViewerFlush_VU"
55 PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
56 {
57   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
58   PetscMPIInt    rank;
59   int            err;
60   PetscErrorCode ierr;
61 
62   PetscFunctionBegin;
63   ierr = MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);CHKERRQ(ierr);
64   if (!rank) {
65     err = fflush(vu->fd);
66     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
67   }
68   PetscFunctionReturn(0);
69 }
70 
71 EXTERN_C_BEGIN
72 #undef __FUNCT__
73 #define __FUNCT__ "PetscViewerFileGetName_VU"
74 PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
75 {
76   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
77 
78   PetscFunctionBegin;
79   *name = vu->filename;
80   PetscFunctionReturn(0);
81 }
82 EXTERN_C_END
83 
84 EXTERN_C_BEGIN
85 #undef __FUNCT__
86 #define __FUNCT__ "PetscViewerFileSetName_VU"
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;
92   PetscErrorCode ierr;
93 
94   PetscFunctionBegin;
95   if (!name) PetscFunctionReturn(0);
96   ierr = PetscViewerFileClose_VU(viewer);CHKERRQ(ierr);
97   ierr = MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);CHKERRQ(ierr);
98   if (rank != 0) PetscFunctionReturn(0);
99   ierr = PetscStrallocpy(name, &vu->filename);CHKERRQ(ierr);
100   ierr = PetscFixFilename(name, fname);CHKERRQ(ierr);
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) vu->fd = fopen(fname, "w+");
114     break;
115   case FILE_MODE_APPEND_UPDATE:
116     /* I really want a file which is opened at the end for updating,
117        not a+, which opens at the beginning, but makes writes at the end.
118     */
119     vu->fd = fopen(fname, "r+");
120     if (!vu->fd) vu->fd = fopen(fname, "w+");
121     else {
122       ierr = fseek(vu->fd, 0, SEEK_END);CHKERRQ(ierr);
123     }
124     break;
125   default:
126     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
127   }
128 
129   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
130 #if defined(PETSC_USE_LOG)
131   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
132 #endif
133   PetscFunctionReturn(0);
134 }
135 EXTERN_C_END
136 
137 EXTERN_C_BEGIN
138 #undef __FUNCT__
139 #define __FUNCT__ "PetscViewerCreate_VU"
140 PetscErrorCode  PetscViewerCreate_VU(PetscViewer viewer)
141 {
142   PetscViewer_VU *vu;
143   PetscErrorCode ierr;
144 
145   PetscFunctionBegin;
146   ierr         = PetscNewLog(viewer,PetscViewer_VU, &vu);CHKERRQ(ierr);
147   viewer->data = (void*) vu;
148 
149   viewer->ops->destroy          = PetscViewerDestroy_VU;
150   viewer->ops->flush            = PetscViewerFlush_VU;
151   viewer->ops->getsingleton     = PETSC_NULL;
152   viewer->ops->restoresingleton = PETSC_NULL;
153   viewer->format                = PETSC_VIEWER_DEFAULT;
154   viewer->iformat               = 0;
155 
156   vu->fd          = PETSC_NULL;
157   vu->mode        = FILE_MODE_WRITE;
158   vu->filename    = PETSC_NULL;
159   vu->vecSeen     = PETSC_FALSE;
160   vu->queue       = PETSC_NULL;
161   vu->queueBase   = PETSC_NULL;
162   vu->queueLength = 0;
163 
164   ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
165                                            PetscViewerFileSetName_VU);CHKERRQ(ierr);
166   ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
167                                            PetscViewerFileGetName_VU);CHKERRQ(ierr);
168   PetscFunctionReturn(0);
169 }
170 EXTERN_C_END
171 
172 #undef __FUNCT__
173 #define __FUNCT__ "PetscViewerVUGetPointer"
174 /*@C
175   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
176 
177   Not Collective
178 
179   Input Parameter:
180 . viewer - The PetscViewer
181 
182   Output Parameter:
183 . fd     - The file pointer
184 
185   Level: intermediate
186 
187   Concepts: PetscViewer^file pointer
188   Concepts: file pointer^getting from PetscViewer
189 
190 .seealso: PetscViewerASCIIGetPointer()
191 @*/
192 PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
193 {
194   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
195 
196   PetscFunctionBegin;
197   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
198   PetscValidPointer(fd,2);
199   *fd = vu->fd;
200   PetscFunctionReturn(0);
201 }
202 
203 #undef __FUNCT__
204 #define __FUNCT__ "PetscViewerVUSetMode"
205 /*@C
206   PetscViewerVUSetMode - Sets the mode in which to open the file.
207 
208   Not Collective
209 
210   Input Parameters:
211 + viewer - The PetscViewer
212 - mode   - The file mode
213 
214   Level: intermediate
215 
216 .keywords: Viewer, file, get, pointer
217 .seealso: PetscViewerASCIISetMode()
218 @*/
219 PetscErrorCode  PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
220 {
221   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
222 
223   PetscFunctionBegin;
224   vu->mode = mode;
225   PetscFunctionReturn(0);
226 }
227 
228 #undef __FUNCT__
229 #define __FUNCT__ "PetscViewerVUSetVecSeen"
230 /*@C
231   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
232   a vector. This is usually called internally rather than by a user.
233 
234   Not Collective
235 
236   Input Parameters:
237 + viewer  - The PetscViewer
238 - vecSeen - The flag which indicates whether we have viewed a vector
239 
240   Level: advanced
241 
242 .keywords: Viewer, Vec
243 .seealso: PetscViewerVUGetVecSeen()
244 @*/
245 PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
246 {
247   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
248 
249   PetscFunctionBegin;
250   vu->vecSeen = vecSeen;
251   PetscFunctionReturn(0);
252 }
253 
254 #undef __FUNCT__
255 #define __FUNCT__ "PetscViewerVUGetVecSeen"
256 /*@C
257   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
258   a vector. This is usually called internally rather than by a user.
259 
260   Not Collective
261 
262   Input Parameter:
263 . viewer  - The PetscViewer
264 
265   Output Parameter:
266 . vecSeen - The flag which indicates whether we have viewed a vector
267 
268   Level: advanced
269 
270 .keywords: Viewer, Vec
271 .seealso: PetscViewerVUGetVecSeen()
272 @*/
273 PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
274 {
275   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
276 
277   PetscFunctionBegin;
278   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
279   PetscValidPointer(vecSeen,2);
280   *vecSeen = vu->vecSeen;
281   PetscFunctionReturn(0);
282 }
283 
284 #undef __FUNCT__
285 #define __FUNCT__ "PetscViewerVUPrintDeferred"
286 /*@C
287   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
288 
289   Not Collective
290 
291   Input Parameters:
292 + viewer - The PetscViewer
293 - format - The format string
294 
295   Level: intermediate
296 
297 .keywords: Viewer, print, deferred
298 .seealso: PetscViewerVUFlushDeferred()
299 @*/
300 PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
301 {
302   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
303   va_list        Argp;
304   size_t         fullLength;
305   PrintfQueue    next;
306   PetscErrorCode ierr;
307 
308   PetscFunctionBegin;
309   ierr = PetscNew(struct _PrintfQueue, &next);CHKERRQ(ierr);
310   if (vu->queue) {
311     vu->queue->next = next;
312     vu->queue       = next;
313     vu->queue->next = PETSC_NULL;
314   } else {
315     vu->queueBase   = vu->queue = next;
316   }
317   vu->queueLength++;
318 
319   va_start(Argp, format);
320   ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr);
321   ierr = PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);CHKERRQ(ierr);
322   va_end(Argp);
323   PetscFunctionReturn(0);
324 }
325 
326 #undef __FUNCT__
327 #define __FUNCT__ "PetscViewerVUFlushDeferred"
328 /*@C
329   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
330 
331   Not Collective
332 
333   Input Parameter:
334 + viewer - The PetscViewer
335 
336   Level: intermediate
337 
338 .keywords: Viewer, flush, deferred
339 .seealso: PetscViewerVUPrintDeferred()
340 @*/
341 PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
342 {
343   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
344   PrintfQueue    next = vu->queueBase;
345   PrintfQueue    previous;
346   int            i;
347   PetscErrorCode ierr;
348 
349   PetscFunctionBegin;
350   for (i = 0; i < vu->queueLength; i++) {
351     PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
352     previous = next;
353     next     = next->next;
354     ierr     = PetscFree(previous);CHKERRQ(ierr);
355   }
356   vu->queue       = PETSC_NULL;
357   vu->queueLength = 0;
358   PetscFunctionReturn(0);
359 }
360