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