1 2 #include <petsc-private/viewerimpl.h> /*I "petscsys.h" I*/ 3 #include <stdarg.h> 4 5 #define QUEUESTRINGSIZE 1024 6 7 typedef struct _PrintfQueue *PrintfQueue; 8 struct _PrintfQueue { 9 char string[QUEUESTRINGSIZE]; 10 PrintfQueue next; 11 }; 12 13 typedef struct { 14 FILE *fd; 15 PetscFileMode mode; /* The mode in which to open the file */ 16 char *filename; 17 PetscBool vecSeen; /* The flag indicating whether any vector has been viewed so far */ 18 PrintfQueue queue, queueBase; 19 int queueLength; 20 } PetscViewer_VU; 21 22 #undef __FUNCT__ 23 #define __FUNCT__ "PetscViewerFileClose_VU" 24 static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer) 25 { 26 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 27 PetscErrorCode ierr; 28 29 PetscFunctionBegin; 30 if (vu->vecSeen) { 31 ierr = PetscViewerVUPrintDeferred(viewer, "};\n\n");CHKERRQ(ierr); 32 } 33 ierr = PetscViewerVUFlushDeferred(viewer);CHKERRQ(ierr); 34 ierr = PetscFClose(((PetscObject)viewer)->comm, vu->fd);CHKERRQ(ierr); 35 vu->fd = PETSC_NULL; 36 ierr = PetscFree(vu->filename);CHKERRQ(ierr); 37 PetscFunctionReturn(0); 38 } 39 40 #undef __FUNCT__ 41 #define __FUNCT__ "PetscViewerDestroy_VU" 42 PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer) 43 { 44 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 45 PetscErrorCode ierr; 46 47 PetscFunctionBegin; 48 ierr = PetscViewerFileClose_VU(viewer);CHKERRQ(ierr); 49 ierr = PetscFree(vu);CHKERRQ(ierr); 50 PetscFunctionReturn(0); 51 } 52 53 #undef __FUNCT__ 54 #define __FUNCT__ "PetscViewerFlush_VU" 55 PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer) 56 { 57 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 58 PetscMPIInt rank; 59 int err; 60 PetscErrorCode ierr; 61 62 PetscFunctionBegin; 63 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);CHKERRQ(ierr); 64 if (!rank) { 65 err = fflush(vu->fd); 66 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 67 } 68 PetscFunctionReturn(0); 69 } 70 71 EXTERN_C_BEGIN 72 #undef __FUNCT__ 73 #define __FUNCT__ "PetscViewerFileGetName_VU" 74 PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name) 75 { 76 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 77 78 PetscFunctionBegin; 79 *name = vu->filename; 80 PetscFunctionReturn(0); 81 } 82 EXTERN_C_END 83 84 EXTERN_C_BEGIN 85 #undef __FUNCT__ 86 #define __FUNCT__ "PetscViewerFileSetName_VU" 87 PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[]) 88 { 89 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 90 char fname[PETSC_MAX_PATH_LEN]; 91 int rank; 92 PetscErrorCode ierr; 93 94 PetscFunctionBegin; 95 if (!name) PetscFunctionReturn(0); 96 ierr = PetscViewerFileClose_VU(viewer);CHKERRQ(ierr); 97 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);CHKERRQ(ierr); 98 if (rank != 0) PetscFunctionReturn(0); 99 ierr = PetscStrallocpy(name, &vu->filename);CHKERRQ(ierr); 100 ierr = PetscFixFilename(name, fname);CHKERRQ(ierr); 101 switch (vu->mode) { 102 case FILE_MODE_READ: 103 vu->fd = fopen(fname, "r"); 104 break; 105 case FILE_MODE_WRITE: 106 vu->fd = fopen(fname, "w"); 107 break; 108 case FILE_MODE_APPEND: 109 vu->fd = fopen(fname, "a"); 110 break; 111 case FILE_MODE_UPDATE: 112 vu->fd = fopen(fname, "r+"); 113 if (!vu->fd) { 114 vu->fd = fopen(fname, "w+"); 115 } 116 break; 117 case FILE_MODE_APPEND_UPDATE: 118 /* I really want a file which is opened at the end for updating, 119 not a+, which opens at the beginning, but makes writes at the end. 120 */ 121 vu->fd = fopen(fname, "r+"); 122 if (!vu->fd) { 123 vu->fd = fopen(fname, "w+"); 124 } else { 125 ierr = fseek(vu->fd, 0, SEEK_END);CHKERRQ(ierr); 126 } 127 break; 128 default: 129 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode); 130 } 131 132 if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname); 133 #if defined(PETSC_USE_LOG) 134 PetscLogObjectState((PetscObject) viewer, "File: %s", name); 135 #endif 136 137 PetscFunctionReturn(0); 138 } 139 EXTERN_C_END 140 141 EXTERN_C_BEGIN 142 #undef __FUNCT__ 143 #define __FUNCT__ "PetscViewerCreate_VU" 144 PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer) 145 { 146 PetscViewer_VU *vu; 147 PetscErrorCode ierr; 148 149 PetscFunctionBegin; 150 ierr = PetscNewLog(viewer,PetscViewer_VU, &vu);CHKERRQ(ierr); 151 viewer->data = (void*) vu; 152 153 viewer->ops->destroy = PetscViewerDestroy_VU; 154 viewer->ops->flush = PetscViewerFlush_VU; 155 viewer->ops->getsingleton = PETSC_NULL; 156 viewer->ops->restoresingleton = PETSC_NULL; 157 viewer->format = PETSC_VIEWER_DEFAULT; 158 viewer->iformat = 0; 159 160 vu->fd = PETSC_NULL; 161 vu->mode = FILE_MODE_WRITE; 162 vu->filename = PETSC_NULL; 163 vu->vecSeen = PETSC_FALSE; 164 vu->queue = PETSC_NULL; 165 vu->queueBase = PETSC_NULL; 166 vu->queueLength = 0; 167 168 ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU", 169 PetscViewerFileSetName_VU);CHKERRQ(ierr); 170 ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU", 171 PetscViewerFileGetName_VU);CHKERRQ(ierr); 172 173 PetscFunctionReturn(0); 174 } 175 EXTERN_C_END 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "PetscViewerVUGetPointer" 179 /*@C 180 PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer. 181 182 Not Collective 183 184 Input Parameter: 185 . viewer - The PetscViewer 186 187 Output Parameter: 188 . fd - The file pointer 189 190 Level: intermediate 191 192 Concepts: PetscViewer^file pointer 193 Concepts: file pointer^getting from PetscViewer 194 195 .seealso: PetscViewerASCIIGetPointer() 196 @*/ 197 PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd) 198 { 199 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 200 201 PetscFunctionBegin; 202 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 203 PetscValidPointer(fd,2); 204 *fd = vu->fd; 205 PetscFunctionReturn(0); 206 } 207 208 #undef __FUNCT__ 209 #define __FUNCT__ "PetscViewerVUSetMode" 210 /*@C 211 PetscViewerVUSetMode - Sets the mode in which to open the file. 212 213 Not Collective 214 215 Input Parameters: 216 + viewer - The PetscViewer 217 - mode - The file mode 218 219 Level: intermediate 220 221 .keywords: Viewer, file, get, pointer 222 .seealso: PetscViewerASCIISetMode() 223 @*/ 224 PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode) 225 { 226 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 227 228 PetscFunctionBegin; 229 vu->mode = mode; 230 PetscFunctionReturn(0); 231 } 232 233 #undef __FUNCT__ 234 #define __FUNCT__ "PetscViewerVUSetVecSeen" 235 /*@C 236 PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed 237 a vector. This is usually called internally rather than by a user. 238 239 Not Collective 240 241 Input Parameters: 242 + viewer - The PetscViewer 243 - vecSeen - The flag which indicates whether we have viewed a vector 244 245 Level: advanced 246 247 .keywords: Viewer, Vec 248 .seealso: PetscViewerVUGetVecSeen() 249 @*/ 250 PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen) 251 { 252 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 253 254 PetscFunctionBegin; 255 vu->vecSeen = vecSeen; 256 PetscFunctionReturn(0); 257 } 258 259 #undef __FUNCT__ 260 #define __FUNCT__ "PetscViewerVUGetVecSeen" 261 /*@C 262 PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed 263 a vector. This is usually called internally rather than by a user. 264 265 Not Collective 266 267 Input Parameter: 268 . viewer - The PetscViewer 269 270 Output Parameter: 271 . vecSeen - The flag which indicates whether we have viewed a vector 272 273 Level: advanced 274 275 .keywords: Viewer, Vec 276 .seealso: PetscViewerVUGetVecSeen() 277 @*/ 278 PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen) 279 { 280 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 281 282 PetscFunctionBegin; 283 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 284 PetscValidPointer(vecSeen,2); 285 *vecSeen = vu->vecSeen; 286 PetscFunctionReturn(0); 287 } 288 289 #undef __FUNCT__ 290 #define __FUNCT__ "PetscViewerVUPrintDeferred" 291 /*@C 292 PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file. 293 294 Not Collective 295 296 Input Parameters: 297 + viewer - The PetscViewer 298 - format - The format string 299 300 Level: intermediate 301 302 .keywords: Viewer, print, deferred 303 .seealso: PetscViewerVUFlushDeferred() 304 @*/ 305 PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...) 306 { 307 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 308 va_list Argp; 309 size_t fullLength; 310 PrintfQueue next; 311 PetscErrorCode ierr; 312 313 PetscFunctionBegin; 314 ierr = PetscNew(struct _PrintfQueue, &next);CHKERRQ(ierr); 315 if (vu->queue) { 316 vu->queue->next = next; 317 vu->queue = next; 318 vu->queue->next = PETSC_NULL; 319 } else { 320 vu->queueBase = vu->queue = next; 321 } 322 vu->queueLength++; 323 324 va_start(Argp, format); 325 ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr); 326 ierr = PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);CHKERRQ(ierr); 327 va_end(Argp); 328 PetscFunctionReturn(0); 329 } 330 331 #undef __FUNCT__ 332 #define __FUNCT__ "PetscViewerVUFlushDeferred" 333 /*@C 334 PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file. 335 336 Not Collective 337 338 Input Parameter: 339 + viewer - The PetscViewer 340 341 Level: intermediate 342 343 .keywords: Viewer, flush, deferred 344 .seealso: PetscViewerVUPrintDeferred() 345 @*/ 346 PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer) 347 { 348 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 349 PrintfQueue next = vu->queueBase; 350 PrintfQueue previous; 351 int i; 352 PetscErrorCode ierr; 353 354 PetscFunctionBegin; 355 for (i = 0; i < vu->queueLength; i++) { 356 PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string); 357 previous = next; 358 next = next->next; 359 ierr = PetscFree(previous);CHKERRQ(ierr); 360 } 361 vu->queue = PETSC_NULL; 362 vu->queueLength = 0; 363 PetscFunctionReturn(0); 364 } 365