xref: /petsc/src/sys/classes/viewer/impls/vu/petscvu.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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;
25*48a46eb9SPierre 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+");
110*48a46eb9SPierre 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 
1229371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer) {
1235c6c1daeSBarry Smith   PetscViewer_VU *vu;
1245c6c1daeSBarry Smith 
1255c6c1daeSBarry Smith   PetscFunctionBegin;
1269566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(viewer, &vu));
1275c6c1daeSBarry Smith   viewer->data = (void *)vu;
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_VU;
1305c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_VU;
131559f443fSBarry Smith   viewer->ops->getsubviewer     = NULL;
132559f443fSBarry Smith   viewer->ops->restoresubviewer = NULL;
1335c6c1daeSBarry Smith 
1340298fd71SBarry Smith   vu->fd          = NULL;
1355c6c1daeSBarry Smith   vu->mode        = FILE_MODE_WRITE;
1360298fd71SBarry Smith   vu->filename    = NULL;
1375c6c1daeSBarry Smith   vu->vecSeen     = PETSC_FALSE;
1380298fd71SBarry Smith   vu->queue       = NULL;
1390298fd71SBarry Smith   vu->queueBase   = NULL;
1405c6c1daeSBarry Smith   vu->queueLength = 0;
1415c6c1daeSBarry Smith 
1429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_VU));
1439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_VU));
1449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_VU));
1459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_VU));
1465c6c1daeSBarry Smith   PetscFunctionReturn(0);
1475c6c1daeSBarry Smith }
1485c6c1daeSBarry Smith 
1495c6c1daeSBarry Smith /*@C
1505c6c1daeSBarry Smith   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith   Not Collective
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith   Input Parameter:
1555c6c1daeSBarry Smith . viewer - The PetscViewer
1565c6c1daeSBarry Smith 
1575c6c1daeSBarry Smith   Output Parameter:
1585c6c1daeSBarry Smith . fd     - The file pointer
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith   Level: intermediate
1615c6c1daeSBarry Smith 
162db781477SPatrick Sanan .seealso: `PetscViewerASCIIGetPointer()`
1635c6c1daeSBarry Smith @*/
1649371c9d4SSatish Balay PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd) {
1655c6c1daeSBarry Smith   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
1665c6c1daeSBarry Smith 
1675c6c1daeSBarry Smith   PetscFunctionBegin;
1685c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1695c6c1daeSBarry Smith   PetscValidPointer(fd, 2);
1705c6c1daeSBarry Smith   *fd = vu->fd;
1715c6c1daeSBarry Smith   PetscFunctionReturn(0);
1725c6c1daeSBarry Smith }
1735c6c1daeSBarry Smith 
1745c6c1daeSBarry Smith /*@C
1755c6c1daeSBarry Smith   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
1765c6c1daeSBarry Smith   a vector. This is usually called internally rather than by a user.
1775c6c1daeSBarry Smith 
1785c6c1daeSBarry Smith   Not Collective
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith   Input Parameters:
1815c6c1daeSBarry Smith + viewer  - The PetscViewer
1825c6c1daeSBarry Smith - vecSeen - The flag which indicates whether we have viewed a vector
1835c6c1daeSBarry Smith 
1845c6c1daeSBarry Smith   Level: advanced
1855c6c1daeSBarry Smith 
186db781477SPatrick Sanan .seealso: `PetscViewerVUGetVecSeen()`
1875c6c1daeSBarry Smith @*/
1889371c9d4SSatish Balay PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen) {
1895c6c1daeSBarry Smith   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith   PetscFunctionBegin;
1925c6c1daeSBarry Smith   vu->vecSeen = vecSeen;
1935c6c1daeSBarry Smith   PetscFunctionReturn(0);
1945c6c1daeSBarry Smith }
1955c6c1daeSBarry Smith 
1965c6c1daeSBarry Smith /*@C
1975c6c1daeSBarry Smith   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
1985c6c1daeSBarry Smith   a vector. This is usually called internally rather than by a user.
1995c6c1daeSBarry Smith 
2005c6c1daeSBarry Smith   Not Collective
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith   Input Parameter:
2035c6c1daeSBarry Smith . viewer  - The PetscViewer
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   Output Parameter:
2065c6c1daeSBarry Smith . vecSeen - The flag which indicates whether we have viewed a vector
2075c6c1daeSBarry Smith 
2085c6c1daeSBarry Smith   Level: advanced
2095c6c1daeSBarry Smith 
210db781477SPatrick Sanan .seealso: `PetscViewerVUGetVecSeen()`
2115c6c1daeSBarry Smith @*/
2129371c9d4SSatish Balay PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool *vecSeen) {
2135c6c1daeSBarry Smith   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith   PetscFunctionBegin;
2165c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
217dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(vecSeen, 2);
2185c6c1daeSBarry Smith   *vecSeen = vu->vecSeen;
2195c6c1daeSBarry Smith   PetscFunctionReturn(0);
2205c6c1daeSBarry Smith }
2215c6c1daeSBarry Smith 
2225c6c1daeSBarry Smith /*@C
2235c6c1daeSBarry Smith   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
2245c6c1daeSBarry Smith 
2255c6c1daeSBarry Smith   Not Collective
2265c6c1daeSBarry Smith 
2275c6c1daeSBarry Smith   Input Parameters:
2285c6c1daeSBarry Smith + viewer - The PetscViewer
2295c6c1daeSBarry Smith - format - The format string
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   Level: intermediate
2325c6c1daeSBarry Smith 
233db781477SPatrick Sanan .seealso: `PetscViewerVUFlushDeferred()`
2345c6c1daeSBarry Smith @*/
2359371c9d4SSatish Balay PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...) {
2365c6c1daeSBarry Smith   PetscViewer_VU *vu = (PetscViewer_VU *)viewer->data;
2375c6c1daeSBarry Smith   va_list         Argp;
2385c6c1daeSBarry Smith   size_t          fullLength;
2395c6c1daeSBarry Smith   PrintfQueue     next;
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith   PetscFunctionBegin;
2429566063dSJacob Faibussowitsch   PetscCall(PetscNew(&next));
2435c6c1daeSBarry Smith   if (vu->queue) {
2445c6c1daeSBarry Smith     vu->queue->next = next;
2455c6c1daeSBarry Smith     vu->queue       = next;
2460298fd71SBarry Smith     vu->queue->next = NULL;
2475c6c1daeSBarry Smith   } else {
2485c6c1daeSBarry Smith     vu->queueBase = vu->queue = next;
2495c6c1daeSBarry Smith   }
2505c6c1daeSBarry Smith   vu->queueLength++;
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith   va_start(Argp, format);
2539566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(next->string, QUEUESTRINGSIZE));
2549566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(next->string, QUEUESTRINGSIZE, format, &fullLength, Argp));
2555c6c1daeSBarry Smith   va_end(Argp);
2565c6c1daeSBarry Smith   PetscFunctionReturn(0);
2575c6c1daeSBarry Smith }
2585c6c1daeSBarry Smith 
2595c6c1daeSBarry Smith /*@C
2605c6c1daeSBarry Smith   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith   Not Collective
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith   Input Parameter:
265a2b725a8SWilliam Gropp . viewer - The PetscViewer
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith   Level: intermediate
2685c6c1daeSBarry Smith 
269db781477SPatrick Sanan .seealso: `PetscViewerVUPrintDeferred()`
2705c6c1daeSBarry Smith @*/
2719371c9d4SSatish Balay PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer) {
2725c6c1daeSBarry Smith   PetscViewer_VU *vu   = (PetscViewer_VU *)viewer->data;
2735c6c1daeSBarry Smith   PrintfQueue     next = vu->queueBase;
2745c6c1daeSBarry Smith   PrintfQueue     previous;
2755c6c1daeSBarry Smith   int             i;
2765c6c1daeSBarry Smith 
2775c6c1daeSBarry Smith   PetscFunctionBegin;
2785c6c1daeSBarry Smith   for (i = 0; i < vu->queueLength; i++) {
279ce94432eSBarry Smith     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
2805c6c1daeSBarry Smith     previous = next;
2815c6c1daeSBarry Smith     next     = next->next;
2829566063dSJacob Faibussowitsch     PetscCall(PetscFree(previous));
2835c6c1daeSBarry Smith   }
2840298fd71SBarry Smith   vu->queue       = NULL;
2855c6c1daeSBarry Smith   vu->queueLength = 0;
2865c6c1daeSBarry Smith   PetscFunctionReturn(0);
2875c6c1daeSBarry Smith }
288