xref: /petsc/src/sys/classes/viewer/impls/vu/petscvu.c (revision af0996ce37bc06907c37d8d91773840993d61e62)
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,&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 
148   vu->fd          = NULL;
149   vu->mode        = FILE_MODE_WRITE;
150   vu->filename    = NULL;
151   vu->vecSeen     = PETSC_FALSE;
152   vu->queue       = NULL;
153   vu->queueBase   = NULL;
154   vu->queueLength = 0;
155 
156   ierr = PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);CHKERRQ(ierr);
157   ierr = PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);CHKERRQ(ierr);
158   PetscFunctionReturn(0);
159 }
160 
161 #undef __FUNCT__
162 #define __FUNCT__ "PetscViewerVUGetPointer"
163 /*@C
164   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
165 
166   Not Collective
167 
168   Input Parameter:
169 . viewer - The PetscViewer
170 
171   Output Parameter:
172 . fd     - The file pointer
173 
174   Level: intermediate
175 
176   Concepts: PetscViewer^file pointer
177   Concepts: file pointer^getting from PetscViewer
178 
179 .seealso: PetscViewerASCIIGetPointer()
180 @*/
181 PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
182 {
183   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
184 
185   PetscFunctionBegin;
186   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
187   PetscValidPointer(fd,2);
188   *fd = vu->fd;
189   PetscFunctionReturn(0);
190 }
191 
192 #undef __FUNCT__
193 #define __FUNCT__ "PetscViewerVUSetMode"
194 /*@C
195   PetscViewerVUSetMode - Sets the mode in which to open the file.
196 
197   Not Collective
198 
199   Input Parameters:
200 + viewer - The PetscViewer
201 - mode   - The file mode
202 
203   Level: intermediate
204 
205 .keywords: Viewer, file, get, pointer
206 .seealso: PetscViewerASCIISetMode()
207 @*/
208 PetscErrorCode  PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
209 {
210   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
211 
212   PetscFunctionBegin;
213   vu->mode = mode;
214   PetscFunctionReturn(0);
215 }
216 
217 #undef __FUNCT__
218 #define __FUNCT__ "PetscViewerVUSetVecSeen"
219 /*@C
220   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
221   a vector. This is usually called internally rather than by a user.
222 
223   Not Collective
224 
225   Input Parameters:
226 + viewer  - The PetscViewer
227 - vecSeen - The flag which indicates whether we have viewed a vector
228 
229   Level: advanced
230 
231 .keywords: Viewer, Vec
232 .seealso: PetscViewerVUGetVecSeen()
233 @*/
234 PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
235 {
236   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
237 
238   PetscFunctionBegin;
239   vu->vecSeen = vecSeen;
240   PetscFunctionReturn(0);
241 }
242 
243 #undef __FUNCT__
244 #define __FUNCT__ "PetscViewerVUGetVecSeen"
245 /*@C
246   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
247   a vector. This is usually called internally rather than by a user.
248 
249   Not Collective
250 
251   Input Parameter:
252 . viewer  - The PetscViewer
253 
254   Output Parameter:
255 . vecSeen - The flag which indicates whether we have viewed a vector
256 
257   Level: advanced
258 
259 .keywords: Viewer, Vec
260 .seealso: PetscViewerVUGetVecSeen()
261 @*/
262 PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
263 {
264   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
265 
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
268   PetscValidPointer(vecSeen,2);
269   *vecSeen = vu->vecSeen;
270   PetscFunctionReturn(0);
271 }
272 
273 #undef __FUNCT__
274 #define __FUNCT__ "PetscViewerVUPrintDeferred"
275 /*@C
276   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
277 
278   Not Collective
279 
280   Input Parameters:
281 + viewer - The PetscViewer
282 - format - The format string
283 
284   Level: intermediate
285 
286 .keywords: Viewer, print, deferred
287 .seealso: PetscViewerVUFlushDeferred()
288 @*/
289 PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
290 {
291   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
292   va_list        Argp;
293   size_t         fullLength;
294   PrintfQueue    next;
295   PetscErrorCode ierr;
296 
297   PetscFunctionBegin;
298   ierr = PetscNew(&next);CHKERRQ(ierr);
299   if (vu->queue) {
300     vu->queue->next = next;
301     vu->queue       = next;
302     vu->queue->next = NULL;
303   } else {
304     vu->queueBase   = vu->queue = next;
305   }
306   vu->queueLength++;
307 
308   va_start(Argp, format);
309   ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr);
310   ierr = PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);CHKERRQ(ierr);
311   va_end(Argp);
312   PetscFunctionReturn(0);
313 }
314 
315 #undef __FUNCT__
316 #define __FUNCT__ "PetscViewerVUFlushDeferred"
317 /*@C
318   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
319 
320   Not Collective
321 
322   Input Parameter:
323 + viewer - The PetscViewer
324 
325   Level: intermediate
326 
327 .keywords: Viewer, flush, deferred
328 .seealso: PetscViewerVUPrintDeferred()
329 @*/
330 PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
331 {
332   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
333   PrintfQueue    next = vu->queueBase;
334   PrintfQueue    previous;
335   int            i;
336   PetscErrorCode ierr;
337 
338   PetscFunctionBegin;
339   for (i = 0; i < vu->queueLength; i++) {
340     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
341     previous = next;
342     next     = next->next;
343     ierr     = PetscFree(previous);CHKERRQ(ierr);
344   }
345   vu->queue       = NULL;
346   vu->queueLength = 0;
347   PetscFunctionReturn(0);
348 }
349