Actual source code: petscvu.c

petsc-3.4.5 2014-06-29
  2: #include <petsc-private/viewerimpl.h>  /*I     "petscsys.h"   I*/

  4: #define QUEUESTRINGSIZE 1024

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

 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;

 23: static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
 24: {
 25:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

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

 41: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
 42: {
 43:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

 47:   PetscViewerFileClose_VU(viewer);
 48:   PetscFree(vu);
 49:   return(0);
 50: }

 54: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
 55: {
 56:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
 57:   PetscMPIInt    rank;
 58:   int            err;

 62:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
 63:   if (!rank) {
 64:     err = fflush(vu->fd);
 65:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
 66:   }
 67:   return(0);
 68: }

 72: PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
 73: {
 74:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

 77:   *name = vu->filename;
 78:   return(0);
 79: }

 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;

 91:   if (!name) return(0);
 92:   PetscViewerFileClose_VU(viewer);
 93:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
 94:   if (rank != 0) return(0);
 95:   PetscStrallocpy(name, &vu->filename);
 96:   PetscFixFilename(name, fname);
 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:       fseek(vu->fd, 0, SEEK_END);
119:     }
120:     break;
121:   default:
122:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
123:   }

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:   return(0);
130: }

134: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
135: {
136:   PetscViewer_VU *vu;

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

143:   viewer->ops->destroy          = PetscViewerDestroy_VU;
144:   viewer->ops->flush            = PetscViewerFlush_VU;
145:   viewer->ops->getsingleton     = NULL;
146:   viewer->ops->restoresingleton = NULL;

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;

156:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
157:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
158:   return(0);
159: }

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

166:   Not Collective

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

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

174:   Level: intermediate

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

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

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

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

197:   Not Collective

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

203:   Level: intermediate

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;

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

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.

223:   Not Collective

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

229:   Level: advanced

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

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

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.

249:   Not Collective

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

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

257:   Level: advanced

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

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

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

278:   Not Collective

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

284:   Level: intermediate

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;

298:   PetscNew(struct _PrintfQueue, &next);
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++;

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

317: /*@C
318:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

320:   Not Collective

322:   Input Parameter:
323: + viewer - The PetscViewer

325:   Level: intermediate

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;

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:     PetscFree(previous);
344:   }
345:   vu->queue       = NULL;
346:   vu->queueLength = 0;
347:   return(0);
348: }