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