Actual source code: petscvu.c

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

  6: #define QUEUESTRINGSIZE 1024

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

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

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

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

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

 50:   MPI_Comm_rank(viewer->comm, &rank);
 51:   if (!rank) fflush(vu->fd);
 52:   return(0);
 53: }

 58: PetscErrorCode PetscViewerGetFilename_VU(PetscViewer viewer, char **name)
 59: {
 60:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 63:   *name = vu->filename;
 64:   return(0);
 65: }

 71: PetscErrorCode PetscViewerSetFilename_VU(PetscViewer viewer, const char name[])
 72: {
 73:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
 74:   char           fname[PETSC_MAX_PATH_LEN];
 75:   int            rank;

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

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

120:   return(0);
121: }

127: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
128: {
129:   PetscViewer_VU *vu;

133:   PetscNew(PetscViewer_VU, &vu);
134:   viewer->data = (void*) vu;

136:   viewer->ops->destroy          = PetscViewerDestroy_VU;
137:   viewer->ops->flush            = PetscViewerFlush_VU;
138:   viewer->ops->getsingleton     = PETSC_NULL;
139:   viewer->ops->restoresingleton = PETSC_NULL;
140:   viewer->format                = PETSC_VIEWER_ASCII_DEFAULT;
141:   viewer->iformat               = 0;

143:   vu->fd          = PETSC_NULL;
144:   vu->mode        = FILE_MODE_WRITE;
145:   vu->filename    = PETSC_NULL;
146:   vu->vecSeen     = PETSC_FALSE;
147:   vu->queue       = PETSC_NULL;
148:   vu->queueBase   = PETSC_NULL;
149:   vu->queueLength = 0;

151:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerSetFilename_C", "PetscViewerSetFilename_VU",
152:                                            PetscViewerSetFilename_VU);
153:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerGetFilename_C", "PetscViewerGetFilename_VU",
154:                                            PetscViewerGetFilename_VU);

156:   return(0);
157: }

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

165:   Not Collective

167:   Input Parameter:
168: . viewer - The PetscViewer

170:   Output Parameter:
171: . fd     - The file pointer

173:   Level: intermediate

175:   Concepts: PetscViewer^file pointer
176:   Concepts: file pointer^getting from PetscViewer

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

187:   *fd = vu->fd;
188:   return(0);
189: }

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

196:   Not Collective

198:   Input Parameters:
199: + viewer - The PetscViewer
200: - mode   - The file mode

202:   Level: intermediate

204: .keywords: Viewer, file, get, pointer
205: .seealso: PetscViewerASCIISetMode()
206: @*/
207: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
208: {
209:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

212:   vu->mode = mode;
213:   return(0);
214: }

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

222:   Not Collective

224:   Input Parameters:
225: + viewer  - The PetscViewer
226: - vecSeen - The flag which indicates whether we have viewed a vector

228:   Level: advanced

230: .keywords: Viewer, Vec
231: .seealso: PetscViewerVUGetVecSeen()
232: @*/
233: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
234: {
235:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

238:   vu->vecSeen = vecSeen;
239:   return(0);
240: }

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

248:   Not Collective

250:   Input Parameter:
251: . viewer  - The PetscViewer

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

256:   Level: advanced

258: .keywords: Viewer, Vec
259: .seealso: PetscViewerVUGetVecSeen()
260: @*/
261: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
262: {
263:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

268:   *vecSeen = vu->vecSeen;
269:   return(0);
270: }

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

277:   Not Collective

279:   Input Parameters:
280: + viewer - The PetscViewer
281: - format - The format string

283:   Level: intermediate

285: .keywords: Viewer, print, deferred
286: .seealso: PetscViewerVUFlushDeferred()
287: @*/
288: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
289: {
290:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
291:   va_list        Argp;
292:   PrintfQueue    next;

296:   PetscNew(struct _PrintfQueue, &next);
297:   if (vu->queue != PETSC_NULL) {
298:     vu->queue->next = next;
299:     vu->queue       = next;
300:     vu->queue->next = PETSC_NULL;
301:   } else {
302:     vu->queueBase   = vu->queue = next;
303:   }
304:   vu->queueLength++;

306:   va_start(Argp, format);
307:   PetscMemzero(next->string,QUEUESTRINGSIZE);
308:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format, Argp);
309:   va_end(Argp);
310:   return(0);
311: }

315: /*@C
316:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

318:   Not Collective

320:   Input Parameter:
321: + viewer - The PetscViewer

323:   Level: intermediate

325: .keywords: Viewer, flush, deferred
326: .seealso: PetscViewerVUPrintDeferred()
327: @*/
328: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
329: {
330:   PetscViewer_VU *vu   = (PetscViewer_VU *) viewer->data;
331:   PrintfQueue    next = vu->queueBase;
332:   PrintfQueue    previous;
333:   int            i;

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