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) {
 26:     PetscViewerVUPrintDeferred(viewer, "};\n\n");
 27:   }
 28:   PetscViewerVUFlushDeferred(viewer);
 29:   PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
 30:   vu->fd = NULL;
 31:   PetscFree(vu->filename);
 32:   return 0;
 33: }

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

 39:   PetscViewerFileClose_VU(viewer);
 40:   PetscFree(vu);
 41:   return 0;
 42: }

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

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

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

 62:   vu->mode = mode;
 63:   return 0;
 64: }

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

 70:   *type = vu->mode;
 71:   return 0;
 72: }

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

 78:   *name = vu->filename;
 79:   return 0;
 80: }

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

 88:   if (!name) return 0;
 89:   PetscViewerFileClose_VU(viewer);
 90:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
 91:   if (rank != 0) return 0;
 92:   PetscStrallocpy(name, &vu->filename);
 93:   PetscFixFilename(name, fname);
 94:   switch (vu->mode) {
 95:   case FILE_MODE_READ:
 96:     vu->fd = fopen(fname, "r");
 97:     break;
 98:   case FILE_MODE_WRITE:
 99:     vu->fd = fopen(fname, "w");
100:     break;
101:   case FILE_MODE_APPEND:
102:     vu->fd = fopen(fname, "a");
103:     break;
104:   case FILE_MODE_UPDATE:
105:     vu->fd = fopen(fname, "r+");
106:     if (!vu->fd) vu->fd = fopen(fname, "w+");
107:     break;
108:   case FILE_MODE_APPEND_UPDATE:
109:     /* I really want a file which is opened at the end for updating,
110:        not a+, which opens at the beginning, but makes writes at the end.
111:     */
112:     vu->fd = fopen(fname, "r+");
113:     if (!vu->fd) vu->fd = fopen(fname, "w+");
114:     else {
115:       fseek(vu->fd, 0, SEEK_END);
116:     }
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: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
130: {
131:   PetscViewer_VU *vu;

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

136:   viewer->ops->destroy          = PetscViewerDestroy_VU;
137:   viewer->ops->flush            = PetscViewerFlush_VU;
138:   viewer->ops->getsubviewer     = NULL;
139:   viewer->ops->restoresubviewer = NULL;

141:   vu->fd          = NULL;
142:   vu->mode        = FILE_MODE_WRITE;
143:   vu->filename    = NULL;
144:   vu->vecSeen     = PETSC_FALSE;
145:   vu->queue       = NULL;
146:   vu->queueBase   = NULL;
147:   vu->queueLength = 0;

149:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
150:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
151:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VU);
152:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_VU);
153:   return 0;
154: }

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

159:   Not Collective

161:   Input Parameter:
162: . viewer - The PetscViewer

164:   Output Parameter:
165: . fd     - The file pointer

167:   Level: intermediate

169: .seealso: PetscViewerASCIIGetPointer()
170: @*/
171: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
172: {
173:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

177:   *fd = vu->fd;
178:   return 0;
179: }

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

185:   Not Collective

187:   Input Parameters:
188: + viewer  - The PetscViewer
189: - vecSeen - The flag which indicates whether we have viewed a vector

191:   Level: advanced

193: .seealso: PetscViewerVUGetVecSeen()
194: @*/
195: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
196: {
197:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

199:   vu->vecSeen = vecSeen;
200:   return 0;
201: }

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

207:   Not Collective

209:   Input Parameter:
210: . viewer  - The PetscViewer

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

215:   Level: advanced

217: .seealso: PetscViewerVUGetVecSeen()
218: @*/
219: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
220: {
221:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

225:   *vecSeen = vu->vecSeen;
226:   return 0;
227: }

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

232:   Not Collective

234:   Input Parameters:
235: + viewer - The PetscViewer
236: - format - The format string

238:   Level: intermediate

240: .seealso: PetscViewerVUFlushDeferred()
241: @*/
242: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
243: {
244:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
245:   va_list        Argp;
246:   size_t         fullLength;
247:   PrintfQueue    next;

249:   PetscNew(&next);
250:   if (vu->queue) {
251:     vu->queue->next = next;
252:     vu->queue       = next;
253:     vu->queue->next = NULL;
254:   } else {
255:     vu->queueBase   = vu->queue = next;
256:   }
257:   vu->queueLength++;

259:   va_start(Argp, format);
260:   PetscArrayzero(next->string,QUEUESTRINGSIZE);
261:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
262:   va_end(Argp);
263:   return 0;
264: }

266: /*@C
267:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

269:   Not Collective

271:   Input Parameter:
272: . viewer - The PetscViewer

274:   Level: intermediate

276: .seealso: PetscViewerVUPrintDeferred()
277: @*/
278: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
279: {
280:   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
281:   PrintfQueue    next = vu->queueBase;
282:   PrintfQueue    previous;
283:   int            i;

285:   for (i = 0; i < vu->queueLength; i++) {
286:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
287:     previous = next;
288:     next     = next->next;
289:     PetscFree(previous);
290:   }
291:   vu->queue       = NULL;
292:   vu->queueLength = 0;
293:   return 0;
294: }