Actual source code: petscvu.c

  2: #include <private/viewerimpl.h>  /*I     "petscsys.h"   I*/
  3: #include <stdarg.h>

  5: #define QUEUESTRINGSIZE 1024

  7: typedef struct _PrintfQueue *PrintfQueue;
  8: struct _PrintfQueue {
  9:   char        string[QUEUESTRINGSIZE];
 10:   PrintfQueue next;
 11: };

 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;

 24: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
 25: {
 26:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 30:   if (vu->vecSeen) {
 31:     PetscViewerVUPrintDeferred(viewer, "};\n\n");
 32:   }
 33:   PetscViewerVUFlushDeferred(viewer);
 34:   PetscFClose(((PetscObject)viewer)->comm, vu->fd);
 35:   PetscFree(vu->filename);
 36:   PetscFree(vu);
 37:   return(0);
 38: }

 42: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
 43: {
 44:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
 45:   PetscMPIInt    rank;
 46:   int            err;

 50:   MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
 51:   if (!rank) {
 52:     err = fflush(vu->fd);
 53:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
 54:   }
 55:   return(0);
 56: }

 61: PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
 62: {
 63:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 66:   *name = vu->filename;
 67:   return(0);
 68: }

 74: PetscErrorCode  PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
 75: {
 76:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
 77:   char           fname[PETSC_MAX_PATH_LEN];
 78:   int            rank;

 82:   if (!name) return(0);
 83:   MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
 84:   if (rank != 0) return(0);
 85:   PetscStrallocpy(name, &vu->filename);
 86:   PetscFixFilename(name, fname);
 87:   switch(vu->mode) {
 88:   case FILE_MODE_READ:
 89:     vu->fd = fopen(fname, "r");
 90:     break;
 91:   case FILE_MODE_WRITE:
 92:     vu->fd = fopen(fname, "w");
 93:     break;
 94:   case FILE_MODE_APPEND:
 95:     vu->fd = fopen(fname, "a");
 96:     break;
 97:   case FILE_MODE_UPDATE:
 98:     vu->fd = fopen(fname, "r+");
 99:     if (!vu->fd) {
100:       vu->fd = fopen(fname, "w+");
101:     }
102:     break;
103:   case FILE_MODE_APPEND_UPDATE:
104:     /* I really want a file which is opened at the end for updating,
105:        not a+, which opens at the beginning, but makes writes at the end.
106:     */
107:     vu->fd = fopen(fname, "r+");
108:     if (!vu->fd) {
109:       vu->fd = fopen(fname, "w+");
110:     } else {
111:       fseek(vu->fd, 0, SEEK_END);
112:     }
113:     break;
114:   default:
115:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
116:   }

118:   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
119: #if defined(PETSC_USE_LOG)
120:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
121: #endif

123:   return(0);
124: }

130: PetscErrorCode  PetscViewerCreate_VU(PetscViewer viewer)
131: {
132:   PetscViewer_VU *vu;

136:   PetscNewLog(viewer,PetscViewer_VU, &vu);
137:   viewer->data = (void*) vu;

139:   viewer->ops->destroy          = PetscViewerDestroy_VU;
140:   viewer->ops->flush            = PetscViewerFlush_VU;
141:   viewer->ops->getsingleton     = PETSC_NULL;
142:   viewer->ops->restoresingleton = PETSC_NULL;
143:   viewer->format                = PETSC_VIEWER_DEFAULT;
144:   viewer->iformat               = 0;

146:   vu->fd          = PETSC_NULL;
147:   vu->mode        = FILE_MODE_WRITE;
148:   vu->filename    = PETSC_NULL;
149:   vu->vecSeen     = PETSC_FALSE;
150:   vu->queue       = PETSC_NULL;
151:   vu->queueBase   = PETSC_NULL;
152:   vu->queueLength = 0;

154:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
155:                                            PetscViewerFileSetName_VU);
156:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
157:                                            PetscViewerFileGetName_VU);

159:   return(0);
160: }

165: /*@C
166:   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.

168:   Not Collective

170:   Input Parameter:
171: . viewer - The PetscViewer

173:   Output Parameter:
174: . fd     - The file pointer

176:   Level: intermediate

178:   Concepts: PetscViewer^file pointer
179:   Concepts: file pointer^getting from PetscViewer

181: .seealso: PetscViewerASCIIGetPointer()
182: @*/
183: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
184: {
185:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

190:   *fd = vu->fd;
191:   return(0);
192: }

196: /*@C
197:   PetscViewerVUSetMode - Sets the mode in which to open the file.

199:   Not Collective

201:   Input Parameters:
202: + viewer - The PetscViewer
203: - mode   - The file mode

205:   Level: intermediate

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;

215:   vu->mode = mode;
216:   return(0);
217: }

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.

225:   Not Collective

227:   Input Parameters:
228: + viewer  - The PetscViewer
229: - vecSeen - The flag which indicates whether we have viewed a vector

231:   Level: advanced

233: .keywords: Viewer, Vec
234: .seealso: PetscViewerVUGetVecSeen()
235: @*/
236: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool  vecSeen)
237: {
238:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

241:   vu->vecSeen = vecSeen;
242:   return(0);
243: }

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.

251:   Not Collective

253:   Input Parameter:
254: . viewer  - The PetscViewer

256:   Output Parameter:
257: . vecSeen - The flag which indicates whether we have viewed a vector

259:   Level: advanced

261: .keywords: Viewer, Vec
262: .seealso: PetscViewerVUGetVecSeen()
263: @*/
264: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
265: {
266:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

271:   *vecSeen = vu->vecSeen;
272:   return(0);
273: }

277: /*@C
278:   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.

280:   Not Collective

282:   Input Parameters:
283: + viewer - The PetscViewer
284: - format - The format string

286:   Level: intermediate

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;

300:   PetscNew(struct _PrintfQueue, &next);
301:   if (vu->queue) {
302:     vu->queue->next = next;
303:     vu->queue       = next;
304:     vu->queue->next = PETSC_NULL;
305:   } else {
306:     vu->queueBase   = vu->queue = next;
307:   }
308:   vu->queueLength++;

310:   va_start(Argp, format);
311:   PetscMemzero(next->string,QUEUESTRINGSIZE);
312:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
313:   va_end(Argp);
314:   return(0);
315: }

319: /*@C
320:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

322:   Not Collective

324:   Input Parameter:
325: + viewer - The PetscViewer

327:   Level: intermediate

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;

341:   for(i = 0; i < vu->queueLength; i++) {
342:     PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
343:     previous = next;
344:     next     = next->next;
345:     PetscFree(previous);
346:   }
347:   vu->queue       = PETSC_NULL;
348:   vu->queueLength = 0;
349:   return(0);
350: }