Actual source code: petscvu.c

petsc-3.9.4 2018-09-11
Report Typos and Errors

  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;

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

 37: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
 38: {
 39:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

 43:   PetscViewerFileClose_VU(viewer);
 44:   PetscFree(vu);
 45:   return(0);
 46: }

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

 56:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
 57:   if (!rank) {
 58:     err = fflush(vu->fd);
 59:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
 60:   }
 61:   return(0);
 62: }

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

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

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

 81:   if (!name) return(0);
 82:   PetscViewerFileClose_VU(viewer);
 83:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &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) vu->fd = fopen(fname, "w+");
100:     break;
101:   case FILE_MODE_APPEND_UPDATE:
102:     /* I really want a file which is opened at the end for updating,
103:        not a+, which opens at the beginning, but makes writes at the end.
104:     */
105:     vu->fd = fopen(fname, "r+");
106:     if (!vu->fd) vu->fd = fopen(fname, "w+");
107:     else {
108:       fseek(vu->fd, 0, SEEK_END);
109:     }
110:     break;
111:   default:
112:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
113:   }

115:   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,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
119:   return(0);
120: }

122: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
123: {
124:   PetscViewer_VU *vu;

128:   PetscNewLog(viewer,&vu);
129:   viewer->data = (void*) vu;

131:   viewer->ops->destroy          = PetscViewerDestroy_VU;
132:   viewer->ops->flush            = PetscViewerFlush_VU;
133:   viewer->ops->getsubviewer     = NULL;
134:   viewer->ops->restoresubviewer = NULL;

136:   vu->fd          = NULL;
137:   vu->mode        = FILE_MODE_WRITE;
138:   vu->filename    = NULL;
139:   vu->vecSeen     = PETSC_FALSE;
140:   vu->queue       = NULL;
141:   vu->queueBase   = NULL;
142:   vu->queueLength = 0;

144:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
145:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
146:   return(0);
147: }

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

152:   Not Collective

154:   Input Parameter:
155: . viewer - The PetscViewer

157:   Output Parameter:
158: . fd     - The file pointer

160:   Level: intermediate

162:   Concepts: PetscViewer^file pointer
163:   Concepts: file pointer^getting from PetscViewer

165: .seealso: PetscViewerASCIIGetPointer()
166: @*/
167: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
168: {
169:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

174:   *fd = vu->fd;
175:   return(0);
176: }

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

181:   Not Collective

183:   Input Parameters:
184: + viewer - The PetscViewer
185: - mode   - The file mode

187:   Level: intermediate

189: .keywords: Viewer, file, get, pointer
190: .seealso: PetscViewerASCIISetMode()
191: @*/
192: PetscErrorCode  PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
193: {
194:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

197:   vu->mode = mode;
198:   return(0);
199: }

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

205:   Not Collective

207:   Input Parameters:
208: + viewer  - The PetscViewer
209: - vecSeen - The flag which indicates whether we have viewed a vector

211:   Level: advanced

213: .keywords: Viewer, Vec
214: .seealso: PetscViewerVUGetVecSeen()
215: @*/
216: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
217: {
218:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

221:   vu->vecSeen = vecSeen;
222:   return(0);
223: }

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

229:   Not Collective

231:   Input Parameter:
232: . viewer  - The PetscViewer

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

237:   Level: advanced

239: .keywords: Viewer, Vec
240: .seealso: PetscViewerVUGetVecSeen()
241: @*/
242: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
243: {
244:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

249:   *vecSeen = vu->vecSeen;
250:   return(0);
251: }

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

256:   Not Collective

258:   Input Parameters:
259: + viewer - The PetscViewer
260: - format - The format string

262:   Level: intermediate

264: .keywords: Viewer, print, deferred
265: .seealso: PetscViewerVUFlushDeferred()
266: @*/
267: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
268: {
269:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
270:   va_list        Argp;
271:   size_t         fullLength;
272:   PrintfQueue    next;

276:   PetscNew(&next);
277:   if (vu->queue) {
278:     vu->queue->next = next;
279:     vu->queue       = next;
280:     vu->queue->next = NULL;
281:   } else {
282:     vu->queueBase   = vu->queue = next;
283:   }
284:   vu->queueLength++;

286:   va_start(Argp, format);
287:   PetscMemzero(next->string,QUEUESTRINGSIZE);
288:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
289:   va_end(Argp);
290:   return(0);
291: }

293: /*@C
294:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

296:   Not Collective

298:   Input Parameter:
299: + viewer - The PetscViewer

301:   Level: intermediate

303: .keywords: Viewer, flush, deferred
304: .seealso: PetscViewerVUPrintDeferred()
305: @*/
306: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
307: {
308:   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
309:   PrintfQueue    next = vu->queueBase;
310:   PrintfQueue    previous;
311:   int            i;

315:   for (i = 0; i < vu->queueLength; i++) {
316:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
317:     previous = next;
318:     next     = next->next;
319:     PetscFree(previous);
320:   }
321:   vu->queue       = NULL;
322:   vu->queueLength = 0;
323:   return(0);
324: }