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 21d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer) 22d71ae5a4SJacob Faibussowitsch { 235c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 245c6c1daeSBarry Smith 255c6c1daeSBarry Smith PetscFunctionBegin; 2648a46eb9SPierre Jolivet if (vu->vecSeen) PetscCall(PetscViewerVUPrintDeferred(viewer, "};\n\n")); 279566063dSJacob Faibussowitsch PetscCall(PetscViewerVUFlushDeferred(viewer)); 289566063dSJacob Faibussowitsch PetscCall(PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd)); 290298fd71SBarry Smith vu->fd = NULL; 309566063dSJacob Faibussowitsch PetscCall(PetscFree(vu->filename)); 31*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 325c6c1daeSBarry Smith } 335c6c1daeSBarry Smith 34d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer) 35d71ae5a4SJacob Faibussowitsch { 365c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 375c6c1daeSBarry Smith 385c6c1daeSBarry Smith PetscFunctionBegin; 399566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_VU(viewer)); 409566063dSJacob Faibussowitsch PetscCall(PetscFree(vu)); 412e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL)); 422e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL)); 432e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL)); 442e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL)); 45*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 465c6c1daeSBarry Smith } 475c6c1daeSBarry Smith 48d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer) 49d71ae5a4SJacob Faibussowitsch { 505c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 515c6c1daeSBarry Smith PetscMPIInt rank; 525c6c1daeSBarry Smith int err; 535c6c1daeSBarry Smith 545c6c1daeSBarry Smith PetscFunctionBegin; 559566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 56dd400576SPatrick Sanan if (rank == 0) { 575c6c1daeSBarry Smith err = fflush(vu->fd); 5828b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 595c6c1daeSBarry Smith } 60*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 615c6c1daeSBarry Smith } 625c6c1daeSBarry Smith 63d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode) 64d71ae5a4SJacob Faibussowitsch { 657e4fd573SVaclav Hapla PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 667e4fd573SVaclav Hapla 677e4fd573SVaclav Hapla PetscFunctionBegin; 687e4fd573SVaclav Hapla vu->mode = mode; 69*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 707e4fd573SVaclav Hapla } 717e4fd573SVaclav Hapla 72d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type) 73d71ae5a4SJacob Faibussowitsch { 747e4fd573SVaclav Hapla PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 757e4fd573SVaclav Hapla 767e4fd573SVaclav Hapla PetscFunctionBegin; 777e4fd573SVaclav Hapla *type = vu->mode; 78*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 797e4fd573SVaclav Hapla } 807e4fd573SVaclav Hapla 81d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, const char **name) 82d71ae5a4SJacob Faibussowitsch { 835c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 845c6c1daeSBarry Smith 855c6c1daeSBarry Smith PetscFunctionBegin; 865c6c1daeSBarry Smith *name = vu->filename; 87*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 885c6c1daeSBarry Smith } 895c6c1daeSBarry Smith 90d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[]) 91d71ae5a4SJacob Faibussowitsch { 925c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 935c6c1daeSBarry Smith char fname[PETSC_MAX_PATH_LEN]; 945c6c1daeSBarry Smith int rank; 955c6c1daeSBarry Smith 965c6c1daeSBarry Smith PetscFunctionBegin; 97*3ba16761SJacob Faibussowitsch if (!name) PetscFunctionReturn(PETSC_SUCCESS); 989566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_VU(viewer)); 999566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 100*3ba16761SJacob Faibussowitsch if (rank != 0) PetscFunctionReturn(PETSC_SUCCESS); 1019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &vu->filename)); 1029566063dSJacob Faibussowitsch PetscCall(PetscFixFilename(name, fname)); 1035c6c1daeSBarry Smith switch (vu->mode) { 104d71ae5a4SJacob Faibussowitsch case FILE_MODE_READ: 105d71ae5a4SJacob Faibussowitsch vu->fd = fopen(fname, "r"); 106d71ae5a4SJacob Faibussowitsch break; 107d71ae5a4SJacob Faibussowitsch case FILE_MODE_WRITE: 108d71ae5a4SJacob Faibussowitsch vu->fd = fopen(fname, "w"); 109d71ae5a4SJacob Faibussowitsch break; 110d71ae5a4SJacob Faibussowitsch case FILE_MODE_APPEND: 111d71ae5a4SJacob Faibussowitsch vu->fd = fopen(fname, "a"); 112d71ae5a4SJacob Faibussowitsch break; 1135c6c1daeSBarry Smith case FILE_MODE_UPDATE: 1145c6c1daeSBarry Smith vu->fd = fopen(fname, "r+"); 115a297a907SKarl Rupp if (!vu->fd) vu->fd = fopen(fname, "w+"); 1165c6c1daeSBarry Smith break; 1175c6c1daeSBarry Smith case FILE_MODE_APPEND_UPDATE: 1185c6c1daeSBarry Smith /* I really want a file which is opened at the end for updating, 1195c6c1daeSBarry Smith not a+, which opens at the beginning, but makes writes at the end. 1205c6c1daeSBarry Smith */ 1215c6c1daeSBarry Smith vu->fd = fopen(fname, "r+"); 122a297a907SKarl Rupp if (!vu->fd) vu->fd = fopen(fname, "w+"); 123*3ba16761SJacob Faibussowitsch else { 124*3ba16761SJacob Faibussowitsch int ret = fseek(vu->fd, 0, SEEK_END); 125*3ba16761SJacob Faibussowitsch PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret); 126*3ba16761SJacob Faibussowitsch } 1275c6c1daeSBarry Smith break; 128d71ae5a4SJacob Faibussowitsch default: 129d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vu->mode]); 1305c6c1daeSBarry Smith } 1315c6c1daeSBarry Smith 13228b400f6SJacob Faibussowitsch PetscCheck(vu->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname); 1335c6c1daeSBarry Smith #if defined(PETSC_USE_LOG) 134*3ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name)); 1355c6c1daeSBarry Smith #endif 136*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1375c6c1daeSBarry Smith } 1385c6c1daeSBarry Smith 139811af0c4SBarry Smith /*MC 140811af0c4SBarry Smith PETSCVIEWERVU - A viewer that prints to a VU file 141811af0c4SBarry Smith 142811af0c4SBarry Smith Level: beginner 143811af0c4SBarry Smith 144d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerVUFlushDeferred()`, `PetscViewerVUGetPointer()`, `PetscViewerVUSetVecSeen()`, `PetscViewerVUGetVecSeen()`, 145811af0c4SBarry Smith `PetscViewerVUPrintDeferred()`, `PetscViewerVUFlushDeferred()` 146811af0c4SBarry Smith M*/ 147d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer) 148d71ae5a4SJacob Faibussowitsch { 1495c6c1daeSBarry Smith PetscViewer_VU *vu; 1505c6c1daeSBarry Smith 1515c6c1daeSBarry Smith PetscFunctionBegin; 1524dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&vu)); 1535c6c1daeSBarry Smith viewer->data = (void *)vu; 1545c6c1daeSBarry Smith 1555c6c1daeSBarry Smith viewer->ops->destroy = PetscViewerDestroy_VU; 1565c6c1daeSBarry Smith viewer->ops->flush = PetscViewerFlush_VU; 157559f443fSBarry Smith viewer->ops->getsubviewer = NULL; 158559f443fSBarry Smith viewer->ops->restoresubviewer = NULL; 1595c6c1daeSBarry Smith 1600298fd71SBarry Smith vu->fd = NULL; 1615c6c1daeSBarry Smith vu->mode = FILE_MODE_WRITE; 1620298fd71SBarry Smith vu->filename = NULL; 1635c6c1daeSBarry Smith vu->vecSeen = PETSC_FALSE; 1640298fd71SBarry Smith vu->queue = NULL; 1650298fd71SBarry Smith vu->queueBase = NULL; 1665c6c1daeSBarry Smith vu->queueLength = 0; 1675c6c1daeSBarry Smith 1689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_VU)); 1699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_VU)); 1709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_VU)); 1719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_VU)); 172*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1735c6c1daeSBarry Smith } 1745c6c1daeSBarry Smith 1755c6c1daeSBarry Smith /*@C 176811af0c4SBarry Smith PetscViewerVUGetPointer - Extracts the file pointer from a `PETSCVIEWERVU` `PetscViewer`. 1775c6c1daeSBarry Smith 1785c6c1daeSBarry Smith Not Collective 1795c6c1daeSBarry Smith 1805c6c1daeSBarry Smith Input Parameter: 181811af0c4SBarry Smith . viewer - The `PetscViewer` 1825c6c1daeSBarry Smith 1835c6c1daeSBarry Smith Output Parameter: 1845c6c1daeSBarry Smith . fd - The file pointer 1855c6c1daeSBarry Smith 1865c6c1daeSBarry Smith Level: intermediate 1875c6c1daeSBarry Smith 188d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerASCIIGetPointer()` 1895c6c1daeSBarry Smith @*/ 190d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd) 191d71ae5a4SJacob Faibussowitsch { 1925c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 1935c6c1daeSBarry Smith 1945c6c1daeSBarry Smith PetscFunctionBegin; 1955c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 1965c6c1daeSBarry Smith PetscValidPointer(fd, 2); 1975c6c1daeSBarry Smith *fd = vu->fd; 198*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1995c6c1daeSBarry Smith } 2005c6c1daeSBarry Smith 2015c6c1daeSBarry Smith /*@C 2025c6c1daeSBarry Smith PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed 2035c6c1daeSBarry Smith a vector. This is usually called internally rather than by a user. 2045c6c1daeSBarry Smith 2055c6c1daeSBarry Smith Not Collective 2065c6c1daeSBarry Smith 2075c6c1daeSBarry Smith Input Parameters: 208811af0c4SBarry Smith + viewer - The `PETSCVIEWERVU` `PetscViewer` 2095c6c1daeSBarry Smith - vecSeen - The flag which indicates whether we have viewed a vector 2105c6c1daeSBarry Smith 211811af0c4SBarry Smith Level: developer 2125c6c1daeSBarry Smith 213d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()` 2145c6c1daeSBarry Smith @*/ 215d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen) 216d71ae5a4SJacob Faibussowitsch { 2175c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2185c6c1daeSBarry Smith 2195c6c1daeSBarry Smith PetscFunctionBegin; 2205c6c1daeSBarry Smith vu->vecSeen = vecSeen; 221*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2225c6c1daeSBarry Smith } 2235c6c1daeSBarry Smith 2245c6c1daeSBarry Smith /*@C 2255c6c1daeSBarry Smith PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed 2265c6c1daeSBarry Smith a vector. This is usually called internally rather than by a user. 2275c6c1daeSBarry Smith 2285c6c1daeSBarry Smith Not Collective 2295c6c1daeSBarry Smith 2305c6c1daeSBarry Smith Input Parameter: 231811af0c4SBarry Smith . viewer - The `PETSCVIEWERVU` `PetscViewer` 2325c6c1daeSBarry Smith 2335c6c1daeSBarry Smith Output Parameter: 2345c6c1daeSBarry Smith . vecSeen - The flag which indicates whether we have viewed a vector 2355c6c1daeSBarry Smith 2365c6c1daeSBarry Smith Level: advanced 2375c6c1daeSBarry Smith 238d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUGetVecSeen()` 2395c6c1daeSBarry Smith @*/ 240d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen) 241d71ae5a4SJacob Faibussowitsch { 2425c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2435c6c1daeSBarry Smith 2445c6c1daeSBarry Smith PetscFunctionBegin; 2455c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 246dadcf809SJacob Faibussowitsch PetscValidBoolPointer(vecSeen, 2); 2475c6c1daeSBarry Smith *vecSeen = vu->vecSeen; 248*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2495c6c1daeSBarry Smith } 2505c6c1daeSBarry Smith 2515c6c1daeSBarry Smith /*@C 2525c6c1daeSBarry Smith PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file. 2535c6c1daeSBarry Smith 2545c6c1daeSBarry Smith Not Collective 2555c6c1daeSBarry Smith 2565c6c1daeSBarry Smith Input Parameters: 257811af0c4SBarry Smith + viewer - The `PETSCVIEWERVU` `PetscViewer` 2585c6c1daeSBarry Smith - format - The format string 2595c6c1daeSBarry Smith 2605c6c1daeSBarry Smith Level: intermediate 2615c6c1daeSBarry Smith 262d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUFlushDeferred()` 2635c6c1daeSBarry Smith @*/ 264d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...) 265d71ae5a4SJacob Faibussowitsch { 2665c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 2675c6c1daeSBarry Smith va_list Argp; 2685c6c1daeSBarry Smith size_t fullLength; 2695c6c1daeSBarry Smith PrintfQueue next; 2705c6c1daeSBarry Smith 2715c6c1daeSBarry Smith PetscFunctionBegin; 2729566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 2735c6c1daeSBarry Smith if (vu->queue) { 2745c6c1daeSBarry Smith vu->queue->next = next; 2755c6c1daeSBarry Smith vu->queue = next; 2760298fd71SBarry Smith vu->queue->next = NULL; 2775c6c1daeSBarry Smith } else { 2785c6c1daeSBarry Smith vu->queueBase = vu->queue = next; 2795c6c1daeSBarry Smith } 2805c6c1daeSBarry Smith vu->queueLength++; 2815c6c1daeSBarry Smith 2825c6c1daeSBarry Smith va_start(Argp, format); 2839566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, QUEUESTRINGSIZE)); 2849566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, QUEUESTRINGSIZE, format, &fullLength, Argp)); 2855c6c1daeSBarry Smith va_end(Argp); 286*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2875c6c1daeSBarry Smith } 2885c6c1daeSBarry Smith 2895c6c1daeSBarry Smith /*@C 2905c6c1daeSBarry Smith PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file. 2915c6c1daeSBarry Smith 2925c6c1daeSBarry Smith Not Collective 2935c6c1daeSBarry Smith 2945c6c1daeSBarry Smith Input Parameter: 295811af0c4SBarry Smith . viewer - The `PETSCVIEWERVU` `PetscViewer` 2965c6c1daeSBarry Smith 2975c6c1daeSBarry Smith Level: intermediate 2985c6c1daeSBarry Smith 299d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERVU`, `PetscViewerVUPrintDeferred()` 3005c6c1daeSBarry Smith @*/ 301d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer) 302d71ae5a4SJacob Faibussowitsch { 3035c6c1daeSBarry Smith PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data; 3045c6c1daeSBarry Smith PrintfQueue next = vu->queueBase; 3055c6c1daeSBarry Smith PrintfQueue previous; 3065c6c1daeSBarry Smith int i; 3075c6c1daeSBarry Smith 3085c6c1daeSBarry Smith PetscFunctionBegin; 3095c6c1daeSBarry Smith for (i = 0; i < vu->queueLength; i++) { 310*3ba16761SJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string)); 3115c6c1daeSBarry Smith previous = next; 3125c6c1daeSBarry Smith next = next->next; 3139566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 3145c6c1daeSBarry Smith } 3150298fd71SBarry Smith vu->queue = NULL; 3165c6c1daeSBarry Smith vu->queueLength = 0; 317*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3185c6c1daeSBarry Smith } 319