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