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 PetscFunctionReturn(0); 137 } 138 EXTERN_C_END 139 140 EXTERN_C_BEGIN 141 #undef __FUNCT__ 142 #define __FUNCT__ "PetscViewerCreate_VU" 143 PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer) 144 { 145 PetscViewer_VU *vu; 146 PetscErrorCode ierr; 147 148 PetscFunctionBegin; 149 ierr = PetscNewLog(viewer,PetscViewer_VU, &vu);CHKERRQ(ierr); 150 viewer->data = (void*) vu; 151 152 viewer->ops->destroy = PetscViewerDestroy_VU; 153 viewer->ops->flush = PetscViewerFlush_VU; 154 viewer->ops->getsingleton = PETSC_NULL; 155 viewer->ops->restoresingleton = PETSC_NULL; 156 viewer->format = PETSC_VIEWER_DEFAULT; 157 viewer->iformat = 0; 158 159 vu->fd = PETSC_NULL; 160 vu->mode = FILE_MODE_WRITE; 161 vu->filename = PETSC_NULL; 162 vu->vecSeen = PETSC_FALSE; 163 vu->queue = PETSC_NULL; 164 vu->queueBase = PETSC_NULL; 165 vu->queueLength = 0; 166 167 ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU", 168 PetscViewerFileSetName_VU);CHKERRQ(ierr); 169 ierr = PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU", 170 PetscViewerFileGetName_VU);CHKERRQ(ierr); 171 PetscFunctionReturn(0); 172 } 173 EXTERN_C_END 174 175 #undef __FUNCT__ 176 #define __FUNCT__ "PetscViewerVUGetPointer" 177 /*@C 178 PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer. 179 180 Not Collective 181 182 Input Parameter: 183 . viewer - The PetscViewer 184 185 Output Parameter: 186 . fd - The file pointer 187 188 Level: intermediate 189 190 Concepts: PetscViewer^file pointer 191 Concepts: file pointer^getting from PetscViewer 192 193 .seealso: PetscViewerASCIIGetPointer() 194 @*/ 195 PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd) 196 { 197 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 198 199 PetscFunctionBegin; 200 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 201 PetscValidPointer(fd,2); 202 *fd = vu->fd; 203 PetscFunctionReturn(0); 204 } 205 206 #undef __FUNCT__ 207 #define __FUNCT__ "PetscViewerVUSetMode" 208 /*@C 209 PetscViewerVUSetMode - Sets the mode in which to open the file. 210 211 Not Collective 212 213 Input Parameters: 214 + viewer - The PetscViewer 215 - mode - The file mode 216 217 Level: intermediate 218 219 .keywords: Viewer, file, get, pointer 220 .seealso: PetscViewerASCIISetMode() 221 @*/ 222 PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode) 223 { 224 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 225 226 PetscFunctionBegin; 227 vu->mode = mode; 228 PetscFunctionReturn(0); 229 } 230 231 #undef __FUNCT__ 232 #define __FUNCT__ "PetscViewerVUSetVecSeen" 233 /*@C 234 PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed 235 a vector. This is usually called internally rather than by a user. 236 237 Not Collective 238 239 Input Parameters: 240 + viewer - The PetscViewer 241 - vecSeen - The flag which indicates whether we have viewed a vector 242 243 Level: advanced 244 245 .keywords: Viewer, Vec 246 .seealso: PetscViewerVUGetVecSeen() 247 @*/ 248 PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen) 249 { 250 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 251 252 PetscFunctionBegin; 253 vu->vecSeen = vecSeen; 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "PetscViewerVUGetVecSeen" 259 /*@C 260 PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed 261 a vector. This is usually called internally rather than by a user. 262 263 Not Collective 264 265 Input Parameter: 266 . viewer - The PetscViewer 267 268 Output Parameter: 269 . vecSeen - The flag which indicates whether we have viewed a vector 270 271 Level: advanced 272 273 .keywords: Viewer, Vec 274 .seealso: PetscViewerVUGetVecSeen() 275 @*/ 276 PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen) 277 { 278 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 279 280 PetscFunctionBegin; 281 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 282 PetscValidPointer(vecSeen,2); 283 *vecSeen = vu->vecSeen; 284 PetscFunctionReturn(0); 285 } 286 287 #undef __FUNCT__ 288 #define __FUNCT__ "PetscViewerVUPrintDeferred" 289 /*@C 290 PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file. 291 292 Not Collective 293 294 Input Parameters: 295 + viewer - The PetscViewer 296 - format - The format string 297 298 Level: intermediate 299 300 .keywords: Viewer, print, deferred 301 .seealso: PetscViewerVUFlushDeferred() 302 @*/ 303 PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...) 304 { 305 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 306 va_list Argp; 307 size_t fullLength; 308 PrintfQueue next; 309 PetscErrorCode ierr; 310 311 PetscFunctionBegin; 312 ierr = PetscNew(struct _PrintfQueue, &next);CHKERRQ(ierr); 313 if (vu->queue) { 314 vu->queue->next = next; 315 vu->queue = next; 316 vu->queue->next = PETSC_NULL; 317 } else { 318 vu->queueBase = vu->queue = next; 319 } 320 vu->queueLength++; 321 322 va_start(Argp, format); 323 ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr); 324 ierr = PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);CHKERRQ(ierr); 325 va_end(Argp); 326 PetscFunctionReturn(0); 327 } 328 329 #undef __FUNCT__ 330 #define __FUNCT__ "PetscViewerVUFlushDeferred" 331 /*@C 332 PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file. 333 334 Not Collective 335 336 Input Parameter: 337 + viewer - The PetscViewer 338 339 Level: intermediate 340 341 .keywords: Viewer, flush, deferred 342 .seealso: PetscViewerVUPrintDeferred() 343 @*/ 344 PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer) 345 { 346 PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data; 347 PrintfQueue next = vu->queueBase; 348 PrintfQueue previous; 349 int i; 350 PetscErrorCode ierr; 351 352 PetscFunctionBegin; 353 for (i = 0; i < vu->queueLength; i++) { 354 PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string); 355 previous = next; 356 next = next->next; 357 ierr = PetscFree(previous);CHKERRQ(ierr); 358 } 359 vu->queue = PETSC_NULL; 360 vu->queueLength = 0; 361 PetscFunctionReturn(0); 362 } 363