Date: 2022-03-04T17:36:58+00:00

Actual source code: petscvu.c

      2: #include <petsc/private/viewerimpl.h>

      4: #define QUEUESTRINGSIZE 1024

      6: typedef struct _PrintfQueue *PrintfQueue;
      7: struct _PrintfQueue {
      8:   char        string[QUEUESTRINGSIZE];
      9:   PrintfQueue next;
     10: };

     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;

     21: static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
     22: {
     23:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     27:   if (vu->vecSeen) {
     28:     PetscViewerVUPrintDeferred(viewer, "};\n\n");
     29:   }
     30:   PetscViewerVUFlushDeferred(viewer);
     31:   PetscFClose(PetscObjectComm((PetscObject)viewer), vu->fd);
     32:   vu->fd = NULL;
     33:   PetscFree(vu->filename);
     34:   return(0);
     35: }

     37: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
     38: {
     39:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     43:   PetscViewerFileClose_VU(viewer);
     44:   PetscFree(vu);
     45:   return(0);
     46: }

     48: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
     49: {
     50:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
     51:   PetscMPIInt    rank;
     52:   int            err;

     56:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
     57:   if (rank == 0) {
     58:     err = fflush(vu->fd);
     59:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
     60:   }
     61:   return(0);
     62: }

     64: static PetscErrorCode  PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode)
     65: {
     66:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     69:   vu->mode = mode;
     70:   return(0);
     71: }

     73: static PetscErrorCode  PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type)
     74: {
     75:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     78:   *type = vu->mode;
     79:   return(0);
     80: }

     82: static PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
     83: {
     84:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     87:   *name = vu->filename;
     88:   return(0);
     89: }

     91: static PetscErrorCode  PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
     92: {
     93:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
     94:   char           fname[PETSC_MAX_PATH_LEN];
     95:   int            rank;

     99:   if (!name) return(0);
    100:   PetscViewerFileClose_VU(viewer);
    101:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
    102:   if (rank != 0) return(0);
    103:   PetscStrallocpy(name, &vu->filename);
    104:   PetscFixFilename(name, fname);
    105:   switch (vu->mode) {
    106:   case FILE_MODE_READ:
    107:     vu->fd = fopen(fname, "r");
    108:     break;
    109:   case FILE_MODE_WRITE:
    110:     vu->fd = fopen(fname, "w");
    111:     break;
    112:   case FILE_MODE_APPEND:
    113:     vu->fd = fopen(fname, "a");
    114:     break;
    115:   case FILE_MODE_UPDATE:
    116:     vu->fd = fopen(fname, "r+");
    117:     if (!vu->fd) vu->fd = fopen(fname, "w+");
    118:     break;
    119:   case FILE_MODE_APPEND_UPDATE:
    120:     /* I really want a file which is opened at the end for updating,
    121:        not a+, which opens at the beginning, but makes writes at the end.
    122:     */
    123:     vu->fd = fopen(fname, "r+");
    124:     if (!vu->fd) vu->fd = fopen(fname, "w+");
    125:     else {
    126:       fseek(vu->fd, 0, SEEK_END);
    127:     }
    128:     break;
    129:   default:
    130:     SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP, "Unsupported file mode %s",PetscFileModes[vu->mode]);
    131:   }

    133:   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
    134: #if defined(PETSC_USE_LOG)
    135:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
    136: #endif
    137:   return(0);
    138: }

    140: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
    141: {
    142:   PetscViewer_VU *vu;

    146:   PetscNewLog(viewer,&vu);
    147:   viewer->data = (void*) vu;

    149:   viewer->ops->destroy          = PetscViewerDestroy_VU;
    150:   viewer->ops->flush            = PetscViewerFlush_VU;
    151:   viewer->ops->getsubviewer     = NULL;
    152:   viewer->ops->restoresubviewer = NULL;

    154:   vu->fd          = NULL;
    155:   vu->mode        = FILE_MODE_WRITE;
    156:   vu->filename    = NULL;
    157:   vu->vecSeen     = PETSC_FALSE;
    158:   vu->queue       = NULL;
    159:   vu->queueBase   = NULL;
    160:   vu->queueLength = 0;

    162:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
    163:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
    164:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VU);
    165:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_VU);
    166:   return(0);
    167: }

    169: /*@C
    170:   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.

    172:   Not Collective

    174:   Input Parameter:
    175: . viewer - The PetscViewer

    177:   Output Parameter:
    178: . fd     - The file pointer

    180:   Level: intermediate

    182: .seealso: PetscViewerASCIIGetPointer()
    183: @*/
    184: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
    185: {
    186:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    191:   *fd = vu->fd;
    192:   return(0);
    193: }

    195: /*@C
    196:   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
    197:   a vector. This is usually called internally rather than by a user.

    199:   Not Collective

    201:   Input Parameters:
    202: + viewer  - The PetscViewer
    203: - vecSeen - The flag which indicates whether we have viewed a vector

    205:   Level: advanced

    207: .seealso: PetscViewerVUGetVecSeen()
    208: @*/
    209: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
    210: {
    211:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    214:   vu->vecSeen = vecSeen;
    215:   return(0);
    216: }

    218: /*@C
    219:   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
    220:   a vector. This is usually called internally rather than by a user.

    222:   Not Collective

    224:   Input Parameter:
    225: . viewer  - The PetscViewer

    227:   Output Parameter:
    228: . vecSeen - The flag which indicates whether we have viewed a vector

    230:   Level: advanced

    232: .seealso: PetscViewerVUGetVecSeen()
    233: @*/
    234: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
    235: {
    236:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    241:   *vecSeen = vu->vecSeen;
    242:   return(0);
    243: }

    245: /*@C
    246:   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.

    248:   Not Collective

    250:   Input Parameters:
    251: + viewer - The PetscViewer
    252: - format - The format string

    254:   Level: intermediate

    256: .seealso: PetscViewerVUFlushDeferred()
    257: @*/
    258: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
    259: {
    260:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
    261:   va_list        Argp;
    262:   size_t         fullLength;
    263:   PrintfQueue    next;

    267:   PetscNew(&next);
    268:   if (vu->queue) {
    269:     vu->queue->next = next;
    270:     vu->queue       = next;
    271:     vu->queue->next = NULL;
    272:   } else {
    273:     vu->queueBase   = vu->queue = next;
    274:   }
    275:   vu->queueLength++;

    277:   va_start(Argp, format);
    278:   PetscArrayzero(next->string,QUEUESTRINGSIZE);
    279:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
    280:   va_end(Argp);
    281:   return(0);
    282: }

    284: /*@C
    285:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

    287:   Not Collective

    289:   Input Parameter:
    290: . viewer - The PetscViewer

    292:   Level: intermediate

    294: .seealso: PetscViewerVUPrintDeferred()
    295: @*/
    296: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
    297: {
    298:   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
    299:   PrintfQueue    next = vu->queueBase;
    300:   PrintfQueue    previous;
    301:   int            i;

    305:   for (i = 0; i < vu->queueLength; i++) {
    306:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
    307:     previous = next;
    308:     next     = next->next;
    309:     PetscFree(previous);
    310:   }
    311:   vu->queue       = NULL;
    312:   vu->queueLength = 0;
    313:   return(0);
    314: }