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