Actual source code: petscvu.c


  2: #include <petsc/private/viewerimpl.h>

  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;

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

 25:   if (vu->vecSeen) PetscViewerVUPrintDeferred(viewer, "};\n\n");
 26:   PetscViewerVUFlushDeferred(viewer);
 27:   PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
 28:   vu->fd = NULL;
 29:   PetscFree(vu->filename);
 30:   return 0;
 31: }

 33: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
 34: {
 35:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

 37:   PetscViewerFileClose_VU(viewer);
 38:   PetscFree(vu);
 39:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL);
 40:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL);
 41:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL);
 42:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL);
 43:   return 0;
 44: }

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

 52:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
 53:   if (rank == 0) {
 54:     err = fflush(vu->fd);
 56:   }
 57:   return 0;
 58: }

 60: static PetscErrorCode PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode)
 61: {
 62:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

 64:   vu->mode = mode;
 65:   return 0;
 66: }

 68: static PetscErrorCode PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type)
 69: {
 70:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

 72:   *type = vu->mode;
 73:   return 0;
 74: }

 76: static PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
 77: {
 78:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

 80:   *name = vu->filename;
 81:   return 0;
 82: }

 84: static PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
 85: {
 86:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
 87:   char            fname[PETSC_MAX_PATH_LEN];
 88:   int             rank;

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

123: #if defined(PETSC_USE_LOG)
124:   PetscLogObjectState((PetscObject)viewer, "File: %s", name);
125: #endif
126:   return 0;
127: }

129: /*MC
130:    PETSCVIEWERVU - A viewer that prints to a VU file

132:   Level: beginner

134: .seealso: [](sec_viewers), `PetscViewerVUFlushDeferred()`, `PetscViewerVUGetPointer()`, `PetscViewerVUSetVecSeen()`, `PetscViewerVUGetVecSeen()`,
135:           `PetscViewerVUPrintDeferred()`, `PetscViewerVUFlushDeferred()`
136: M*/
137: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
138: {
139:   PetscViewer_VU *vu;

141:   PetscNew(&vu);
142:   viewer->data = (void *)vu;

144:   viewer->ops->destroy          = PetscViewerDestroy_VU;
145:   viewer->ops->flush            = PetscViewerFlush_VU;
146:   viewer->ops->getsubviewer     = NULL;
147:   viewer->ops->restoresubviewer = NULL;

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

157:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_VU);
158:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_VU);
159:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_VU);
160:   PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_VU);
161:   return 0;
162: }

164: /*@C
165:   PetscViewerVUGetPointer - Extracts the file pointer from a `PETSCVIEWERVU` `PetscViewer`.

167:   Not Collective

169:   Input Parameter:
170: . viewer - The `PetscViewer`

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

175:   Level: intermediate

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

185:   *fd = vu->fd;
186:   return 0;
187: }

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

193:   Not Collective

195:   Input Parameters:
196: + viewer  - The `PETSCVIEWERVU` `PetscViewer`
197: - vecSeen - The flag which indicates whether we have viewed a vector

199:   Level: developer

201: .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()`
202: @*/
203: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
204: {
205:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

207:   vu->vecSeen = vecSeen;
208:   return 0;
209: }

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

215:   Not Collective

217:   Input Parameter:
218: . viewer  - The `PETSCVIEWERVU` `PetscViewer`

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

223:   Level: advanced

225: .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()`
226: @*/
227: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen)
228: {
229:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;

233:   *vecSeen = vu->vecSeen;
234:   return 0;
235: }

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

240:   Not Collective

242:   Input Parameters:
243: + viewer - The `PETSCVIEWERVU` `PetscViewer`
244: - format - The format string

246:   Level: intermediate

248: .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUFlushDeferred()`
249: @*/
250: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
251: {
252:   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
253:   va_list         Argp;
254:   size_t          fullLength;
255:   PrintfQueue     next;

257:   PetscNew(&next);
258:   if (vu->queue) {
259:     vu->queue->next = next;
260:     vu->queue       = next;
261:     vu->queue->next = NULL;
262:   } else {
263:     vu->queueBase = vu->queue = next;
264:   }
265:   vu->queueLength++;

267:   va_start(Argp, format);
268:   PetscArrayzero(next->string, QUEUESTRINGSIZE);
269:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE, format, &fullLength, Argp);
270:   va_end(Argp);
271:   return 0;
272: }

274: /*@C
275:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

277:   Not Collective

279:   Input Parameter:
280: . viewer - The `PETSCVIEWERVU` `PetscViewer`

282:   Level: intermediate

284: .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUPrintDeferred()`
285: @*/
286: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
287: {
288:   PetscViewer_VU *vu   = (PetscViewer_VU *)viewer->data;
289:   PrintfQueue     next = vu->queueBase;
290:   PrintfQueue     previous;
291:   int             i;

293:   for (i = 0; i < vu->queueLength; i++) {
294:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
295:     previous = next;
296:     next     = next->next;
297:     PetscFree(previous);
298:   }
299:   vu->queue       = NULL;
300:   vu->queueLength = 0;
301:   return 0;
302: }