15c6c1daeSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /*I "petscsys.h" I*/ 35c6c1daeSBarry Smith 45c6c1daeSBarry Smith #define QUEUESTRINGSIZE 1024 55c6c1daeSBarry Smith 65c6c1daeSBarry Smith typedef struct _PrintfQueue *PrintfQueue; 75c6c1daeSBarry Smith struct _PrintfQueue { 85c6c1daeSBarry Smith char string[QUEUESTRINGSIZE]; 95c6c1daeSBarry Smith PrintfQueue next; 105c6c1daeSBarry Smith }; 115c6c1daeSBarry Smith 125c6c1daeSBarry Smith typedef struct { 135c6c1daeSBarry Smith FILE *fd; 145c6c1daeSBarry Smith PetscFileMode mode; /* The mode in which to open the file */ 155c6c1daeSBarry Smith char *filename; 165c6c1daeSBarry Smith PetscBool vecSeen; /* The flag indicating whether any vector has been viewed so far */ 175c6c1daeSBarry Smith PrintfQueue queue, queueBase; 185c6c1daeSBarry Smith int queueLength; 195c6c1daeSBarry Smith } PetscViewer_VU; 205c6c1daeSBarry Smith 219371c9d4SSatish Balay static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer) { 225c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 235c6c1daeSBarry Smith 245c6c1daeSBarry Smith PetscFunctionBegin; 2548a46eb9SPierre Jolivet if (vu->vecSeen) PetscCall(PetscViewerVUPrintDeferred(viewer, "};\n\n")); 269566063dSJacob Faibussowitsch PetscCall(PetscViewerVUFlushDeferred(viewer)); 279566063dSJacob Faibussowitsch PetscCall(PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd)); 280298fd71SBarry Smith vu->fd = NULL; 299566063dSJacob Faibussowitsch PetscCall(PetscFree(vu->filename)); 305c6c1daeSBarry Smith PetscFunctionReturn(0); 315c6c1daeSBarry Smith } 325c6c1daeSBarry Smith 339371c9d4SSatish Balay PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer) { 345c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 355c6c1daeSBarry Smith 365c6c1daeSBarry Smith PetscFunctionBegin; 379566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_VU(viewer)); 389566063dSJacob Faibussowitsch PetscCall(PetscFree(vu)); 392e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL)); 402e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL)); 412e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL)); 422e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL)); 435c6c1daeSBarry Smith PetscFunctionReturn(0); 445c6c1daeSBarry Smith } 455c6c1daeSBarry Smith 469371c9d4SSatish Balay PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer) { 475c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 485c6c1daeSBarry Smith PetscMPIInt rank; 495c6c1daeSBarry Smith int err; 505c6c1daeSBarry Smith 515c6c1daeSBarry Smith PetscFunctionBegin; 529566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 53dd400576SPatrick Sanan if (rank == 0) { 545c6c1daeSBarry Smith err = fflush(vu->fd); 5528b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 565c6c1daeSBarry Smith } 575c6c1daeSBarry Smith PetscFunctionReturn(0); 585c6c1daeSBarry Smith } 595c6c1daeSBarry Smith 609371c9d4SSatish Balay static PetscErrorCode PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode) { 617e4fd573SVaclav Hapla PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 627e4fd573SVaclav Hapla 637e4fd573SVaclav Hapla PetscFunctionBegin; 647e4fd573SVaclav Hapla vu->mode = mode; 657e4fd573SVaclav Hapla PetscFunctionReturn(0); 667e4fd573SVaclav Hapla } 677e4fd573SVaclav Hapla 689371c9d4SSatish Balay static PetscErrorCode PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type) { 697e4fd573SVaclav Hapla PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 707e4fd573SVaclav Hapla 717e4fd573SVaclav Hapla PetscFunctionBegin; 727e4fd573SVaclav Hapla *type = vu->mode; 737e4fd573SVaclav Hapla PetscFunctionReturn(0); 747e4fd573SVaclav Hapla } 757e4fd573SVaclav Hapla 769371c9d4SSatish Balay static PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name) { 775c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 785c6c1daeSBarry Smith 795c6c1daeSBarry Smith PetscFunctionBegin; 805c6c1daeSBarry Smith *name = vu->filename; 815c6c1daeSBarry Smith PetscFunctionReturn(0); 825c6c1daeSBarry Smith } 835c6c1daeSBarry Smith 849371c9d4SSatish Balay static PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[]) { 855c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 865c6c1daeSBarry Smith char fname[PETSC_MAX_PATH_LEN]; 875c6c1daeSBarry Smith int rank; 885c6c1daeSBarry Smith 895c6c1daeSBarry Smith PetscFunctionBegin; 905c6c1daeSBarry Smith if (!name) PetscFunctionReturn(0); 919566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_VU(viewer)); 929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 935c6c1daeSBarry Smith if (rank != 0) PetscFunctionReturn(0); 949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &vu->filename)); 959566063dSJacob Faibussowitsch PetscCall(PetscFixFilename(name, fname)); 965c6c1daeSBarry Smith switch (vu->mode) { 979371c9d4SSatish Balay case FILE_MODE_READ: vu->fd = fopen(fname, "r"); break; 989371c9d4SSatish Balay case FILE_MODE_WRITE: vu->fd = fopen(fname, "w"); break; 999371c9d4SSatish Balay case FILE_MODE_APPEND: vu->fd = fopen(fname, "a"); break; 1005c6c1daeSBarry Smith case FILE_MODE_UPDATE: 1015c6c1daeSBarry Smith vu->fd = fopen(fname, "r+"); 102a297a907SKarl Rupp if (!vu->fd) vu->fd = fopen(fname, "w+"); 1035c6c1daeSBarry Smith break; 1045c6c1daeSBarry Smith case FILE_MODE_APPEND_UPDATE: 1055c6c1daeSBarry Smith /* I really want a file which is opened at the end for updating, 1065c6c1daeSBarry Smith not a+, which opens at the beginning, but makes writes at the end. 1075c6c1daeSBarry Smith */ 1085c6c1daeSBarry Smith vu->fd = fopen(fname, "r+"); 109a297a907SKarl Rupp if (!vu->fd) vu->fd = fopen(fname, "w+"); 11048a46eb9SPierre Jolivet else PetscCall(fseek(vu->fd, 0, SEEK_END)); 1115c6c1daeSBarry Smith break; 1129371c9d4SSatish Balay default: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vu->mode]); 1135c6c1daeSBarry Smith } 1145c6c1daeSBarry Smith 11528b400f6SJacob Faibussowitsch PetscCheck(vu->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname); 1165c6c1daeSBarry Smith #if defined(PETSC_USE_LOG) 1175c6c1daeSBarry Smith PetscLogObjectState((PetscObject)viewer, "File: %s", name); 1185c6c1daeSBarry Smith #endif 1195c6c1daeSBarry Smith PetscFunctionReturn(0); 1205c6c1daeSBarry Smith } 1215c6c1daeSBarry Smith 122811af0c4SBarry Smith /*MC 123811af0c4SBarry Smith PETSCVIEWERVU - A viewer that prints to a VU file 124811af0c4SBarry Smith 125811af0c4SBarry Smith Level: beginner 126811af0c4SBarry Smith 127811af0c4SBarry Smith .seealso: `PetscViewerVUFlushDeferred()`, `PetscViewerVUGetPointer()`, `PetscViewerVUSetVecSeen()`, `PetscViewerVUGetVecSeen()`, 128811af0c4SBarry Smith `PetscViewerVUPrintDeferred()`, `PetscViewerVUFlushDeferred()` 129811af0c4SBarry Smith M*/ 1309371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer) { 1315c6c1daeSBarry Smith PetscViewer_VU *vu; 1325c6c1daeSBarry Smith 1335c6c1daeSBarry Smith PetscFunctionBegin; 134*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&vu)); 1355c6c1daeSBarry Smith viewer->data = (void *)vu; 1365c6c1daeSBarry Smith 1375c6c1daeSBarry Smith viewer->ops->destroy = PetscViewerDestroy_VU; 1385c6c1daeSBarry Smith viewer->ops->flush = PetscViewerFlush_VU; 139559f443fSBarry Smith viewer->ops->getsubviewer = NULL; 140559f443fSBarry Smith viewer->ops->restoresubviewer = NULL; 1415c6c1daeSBarry Smith 1420298fd71SBarry Smith vu->fd = NULL; 1435c6c1daeSBarry Smith vu->mode = FILE_MODE_WRITE; 1440298fd71SBarry Smith vu->filename = NULL; 1455c6c1daeSBarry Smith vu->vecSeen = PETSC_FALSE; 1460298fd71SBarry Smith vu->queue = NULL; 1470298fd71SBarry Smith vu->queueBase = NULL; 1485c6c1daeSBarry Smith vu->queueLength = 0; 1495c6c1daeSBarry Smith 1509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_VU)); 1519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_VU)); 1529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_VU)); 1539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_VU)); 1545c6c1daeSBarry Smith PetscFunctionReturn(0); 1555c6c1daeSBarry Smith } 1565c6c1daeSBarry Smith 1575c6c1daeSBarry Smith /*@C 158811af0c4SBarry Smith PetscViewerVUGetPointer - Extracts the file pointer from a `PETSCVIEWERVU` `PetscViewer`. 1595c6c1daeSBarry Smith 1605c6c1daeSBarry Smith Not Collective 1615c6c1daeSBarry Smith 1625c6c1daeSBarry Smith Input Parameter: 163811af0c4SBarry Smith . viewer - The `PetscViewer` 1645c6c1daeSBarry Smith 1655c6c1daeSBarry Smith Output Parameter: 1665c6c1daeSBarry Smith . fd - The file pointer 1675c6c1daeSBarry Smith 1685c6c1daeSBarry Smith Level: intermediate 1695c6c1daeSBarry Smith 170811af0c4SBarry Smith .seealso: `PETSCVIEWERVU`, `PetscViewerASCIIGetPointer()` 1715c6c1daeSBarry Smith @*/ 1729371c9d4SSatish Balay PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd) { 1735c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 1745c6c1daeSBarry Smith 1755c6c1daeSBarry Smith PetscFunctionBegin; 1765c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 1775c6c1daeSBarry Smith PetscValidPointer(fd, 2); 1785c6c1daeSBarry Smith *fd = vu->fd; 1795c6c1daeSBarry Smith PetscFunctionReturn(0); 1805c6c1daeSBarry Smith } 1815c6c1daeSBarry Smith 1825c6c1daeSBarry Smith /*@C 1835c6c1daeSBarry Smith PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed 1845c6c1daeSBarry Smith a vector. This is usually called internally rather than by a user. 1855c6c1daeSBarry Smith 1865c6c1daeSBarry Smith Not Collective 1875c6c1daeSBarry Smith 1885c6c1daeSBarry Smith Input Parameters: 189811af0c4SBarry Smith + viewer - The `PETSCVIEWERVU` `PetscViewer` 1905c6c1daeSBarry Smith - vecSeen - The flag which indicates whether we have viewed a vector 1915c6c1daeSBarry Smith 192811af0c4SBarry Smith Level: developer 1935c6c1daeSBarry Smith 194811af0c4SBarry Smith .seealso: `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()` 1955c6c1daeSBarry Smith @*/ 1969371c9d4SSatish Balay PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen) { 1975c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 1985c6c1daeSBarry Smith 1995c6c1daeSBarry Smith PetscFunctionBegin; 2005c6c1daeSBarry Smith vu->vecSeen = vecSeen; 2015c6c1daeSBarry Smith PetscFunctionReturn(0); 2025c6c1daeSBarry Smith } 2035c6c1daeSBarry Smith 2045c6c1daeSBarry Smith /*@C 2055c6c1daeSBarry Smith PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed 2065c6c1daeSBarry Smith a vector. This is usually called internally rather than by a user. 2075c6c1daeSBarry Smith 2085c6c1daeSBarry Smith Not Collective 2095c6c1daeSBarry Smith 2105c6c1daeSBarry Smith Input Parameter: 211811af0c4SBarry Smith . viewer - The `PETSCVIEWERVU` `PetscViewer` 2125c6c1daeSBarry Smith 2135c6c1daeSBarry Smith Output Parameter: 2145c6c1daeSBarry Smith . vecSeen - The flag which indicates whether we have viewed a vector 2155c6c1daeSBarry Smith 2165c6c1daeSBarry Smith Level: advanced 2175c6c1daeSBarry Smith 218811af0c4SBarry Smith .seealso: `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()` 2195c6c1daeSBarry Smith @*/ 2209371c9d4SSatish Balay PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen) { 2215c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2225c6c1daeSBarry Smith 2235c6c1daeSBarry Smith PetscFunctionBegin; 2245c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 225dadcf809SJacob Faibussowitsch PetscValidBoolPointer(vecSeen, 2); 2265c6c1daeSBarry Smith *vecSeen = vu->vecSeen; 2275c6c1daeSBarry Smith PetscFunctionReturn(0); 2285c6c1daeSBarry Smith } 2295c6c1daeSBarry Smith 2305c6c1daeSBarry Smith /*@C 2315c6c1daeSBarry Smith PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file. 2325c6c1daeSBarry Smith 2335c6c1daeSBarry Smith Not Collective 2345c6c1daeSBarry Smith 2355c6c1daeSBarry Smith Input Parameters: 236811af0c4SBarry Smith + viewer - The `PETSCVIEWERVU` `PetscViewer` 2375c6c1daeSBarry Smith - format - The format string 2385c6c1daeSBarry Smith 2395c6c1daeSBarry Smith Level: intermediate 2405c6c1daeSBarry Smith 241811af0c4SBarry Smith .seealso: `PETSCVIEWERVU`, `PetscViewerVUFlushDeferred()` 2425c6c1daeSBarry Smith @*/ 2439371c9d4SSatish Balay PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...) { 2445c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2455c6c1daeSBarry Smith va_list Argp; 2465c6c1daeSBarry Smith size_t fullLength; 2475c6c1daeSBarry Smith PrintfQueue next; 2485c6c1daeSBarry Smith 2495c6c1daeSBarry Smith PetscFunctionBegin; 2509566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 2515c6c1daeSBarry Smith if (vu->queue) { 2525c6c1daeSBarry Smith vu->queue->next = next; 2535c6c1daeSBarry Smith vu->queue = next; 2540298fd71SBarry Smith vu->queue->next = NULL; 2555c6c1daeSBarry Smith } else { 2565c6c1daeSBarry Smith vu->queueBase = vu->queue = next; 2575c6c1daeSBarry Smith } 2585c6c1daeSBarry Smith vu->queueLength++; 2595c6c1daeSBarry Smith 2605c6c1daeSBarry Smith va_start(Argp, format); 2619566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, QUEUESTRINGSIZE)); 2629566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, QUEUESTRINGSIZE, format, &fullLength, Argp)); 2635c6c1daeSBarry Smith va_end(Argp); 2645c6c1daeSBarry Smith PetscFunctionReturn(0); 2655c6c1daeSBarry Smith } 2665c6c1daeSBarry Smith 2675c6c1daeSBarry Smith /*@C 2685c6c1daeSBarry Smith PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file. 2695c6c1daeSBarry Smith 2705c6c1daeSBarry Smith Not Collective 2715c6c1daeSBarry Smith 2725c6c1daeSBarry Smith Input Parameter: 273811af0c4SBarry Smith . viewer - The `PETSCVIEWERVU` `PetscViewer` 2745c6c1daeSBarry Smith 2755c6c1daeSBarry Smith Level: intermediate 2765c6c1daeSBarry Smith 277811af0c4SBarry Smith .seealso: `PETSCVIEWERVU`, `PetscViewerVUPrintDeferred()` 2785c6c1daeSBarry Smith @*/ 2799371c9d4SSatish Balay PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer) { 2805c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2815c6c1daeSBarry Smith PrintfQueue next = vu->queueBase; 2825c6c1daeSBarry Smith PrintfQueue previous; 2835c6c1daeSBarry Smith int i; 2845c6c1daeSBarry Smith 2855c6c1daeSBarry Smith PetscFunctionBegin; 2865c6c1daeSBarry Smith for (i = 0; i < vu->queueLength; i++) { 287ce94432eSBarry Smith PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string); 2885c6c1daeSBarry Smith previous = next; 2895c6c1daeSBarry Smith next = next->next; 2909566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 2915c6c1daeSBarry Smith } 2920298fd71SBarry Smith vu->queue = NULL; 2935c6c1daeSBarry Smith vu->queueLength = 0; 2945c6c1daeSBarry Smith PetscFunctionReturn(0); 2955c6c1daeSBarry Smith } 296