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