Actual source code: petscvu.c

  1: #define PETSC_DLL

 3:  #include ../src/sys/viewer/viewerimpl.h
  4: #include <stdarg.h>
  5: #include "petscfix.h"

  7: #define QUEUESTRINGSIZE 1024

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

 15: typedef struct {
 16:   FILE          *fd;
 17:   PetscFileMode mode;     /* The mode in which to open the file */
 18:   char          *filename;
 19:   PetscTruth    vecSeen;  /* The flag indicating whether any vector has been viewed so far */
 20:   PrintfQueue   queue, queueBase;
 21:   int           queueLength;
 22: } PetscViewer_VU;

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

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

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

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

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

 68:   *name = vu->filename;
 69:   return(0);
 70: }

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

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

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

125:   return(0);
126: }

132: PetscErrorCode  PetscViewerCreate_VU(PetscViewer viewer)
133: {
134:   PetscViewer_VU *vu;

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

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

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

156:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
157:                                            PetscViewerFileSetName_VU);
158:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
159:                                            PetscViewerFileGetName_VU);

161:   return(0);
162: }

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

170:   Not Collective

172:   Input Parameter:
173: . viewer - The PetscViewer

175:   Output Parameter:
176: . fd     - The file pointer

178:   Level: intermediate

180:   Concepts: PetscViewer^file pointer
181:   Concepts: file pointer^getting from PetscViewer

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

192:   *fd = vu->fd;
193:   return(0);
194: }

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

201:   Not Collective

203:   Input Parameters:
204: + viewer - The PetscViewer
205: - mode   - The file mode

207:   Level: intermediate

209: .keywords: Viewer, file, get, pointer
210: .seealso: PetscViewerASCIISetMode()
211: @*/
212: PetscErrorCode  PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
213: {
214:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

217:   vu->mode = mode;
218:   return(0);
219: }

223: /*@C
224:   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
225:   a vector. This is usually called internally rather than by a user.

227:   Not Collective

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

233:   Level: advanced

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

243:   vu->vecSeen = vecSeen;
244:   return(0);
245: }

249: /*@C
250:   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
251:   a vector. This is usually called internally rather than by a user.

253:   Not Collective

255:   Input Parameter:
256: . viewer  - The PetscViewer

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

261:   Level: advanced

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

273:   *vecSeen = vu->vecSeen;
274:   return(0);
275: }

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

282:   Not Collective

284:   Input Parameters:
285: + viewer - The PetscViewer
286: - format - The format string

288:   Level: intermediate

290: .keywords: Viewer, print, deferred
291: .seealso: PetscViewerVUFlushDeferred()
292: @*/
293: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
294: {
295:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
296:   va_list        Argp;
297:   int            fullLength;
298:   PrintfQueue    next;

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

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

321: /*@C
322:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

324:   Not Collective

326:   Input Parameter:
327: + viewer - The PetscViewer

329:   Level: intermediate

331: .keywords: Viewer, flush, deferred
332: .seealso: PetscViewerVUPrintDeferred()
333: @*/
334: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
335: {
336:   PetscViewer_VU *vu   = (PetscViewer_VU *) viewer->data;
337:   PrintfQueue    next = vu->queueBase;
338:   PrintfQueue    previous;
339:   int            i;

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