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;

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

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

     39:   PetscViewerFileClose_VU(viewer);
     40:   PetscFree(vu);
     41:   return 0;
     42: }

     44: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
     45: {
     46:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
     47:   PetscMPIInt    rank;
     48:   int            err;

     50:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
     51:   if (rank == 0) {
     52:     err = fflush(vu->fd);
     54:   }
     55:   return 0;
     56: }

     58: static PetscErrorCode  PetscViewerFileSetMode_VU(PetscViewer viewer, PetscFileMode mode)
     59: {
     60:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     62:   vu->mode = mode;
     63:   return 0;
     64: }

     66: static PetscErrorCode  PetscViewerFileGetMode_VU(PetscViewer viewer, PetscFileMode *type)
     67: {
     68:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     70:   *type = vu->mode;
     71:   return 0;
     72: }

     74: static PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
     75: {
     76:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     78:   *name = vu->filename;
     79:   return 0;
     80: }

     82: static PetscErrorCode  PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
     83: {
     84:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
     85:   char           fname[PETSC_MAX_PATH_LEN];
     86:   int            rank;

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

    123: #if defined(PETSC_USE_LOG)
    124:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
    125: #endif
    126:   return 0;
    127: }

    129: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
    130: {
    131:   PetscViewer_VU *vu;

    133:   PetscNewLog(viewer,&vu);
    134:   viewer->data = (void*) vu;

    136:   viewer->ops->destroy          = PetscViewerDestroy_VU;
    137:   viewer->ops->flush            = PetscViewerFlush_VU;
    138:   viewer->ops->getsubviewer     = NULL;
    139:   viewer->ops->restoresubviewer = NULL;

    141:   vu->fd          = NULL;
    142:   vu->mode        = FILE_MODE_WRITE;
    143:   vu->filename    = NULL;
    144:   vu->vecSeen     = PETSC_FALSE;
    145:   vu->queue       = NULL;
    146:   vu->queueBase   = NULL;
    147:   vu->queueLength = 0;

    149:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
    150:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
    151:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VU);
    152:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_VU);
    153:   return 0;
    154: }

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

    159:   Not Collective

    161:   Input Parameter:
    162: . viewer - The PetscViewer

    164:   Output Parameter:
    165: . fd     - The file pointer

    167:   Level: intermediate

    169: .seealso: PetscViewerASCIIGetPointer()
    170: @*/
    171: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
    172: {
    173:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    177:   *fd = vu->fd;
    178:   return 0;
    179: }

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

    185:   Not Collective

    187:   Input Parameters:
    188: + viewer  - The PetscViewer
    189: - vecSeen - The flag which indicates whether we have viewed a vector

    191:   Level: advanced

    193: .seealso: PetscViewerVUGetVecSeen()
    194: @*/
    195: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool vecSeen)
    196: {
    197:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    199:   vu->vecSeen = vecSeen;
    200:   return 0;
    201: }

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

    207:   Not Collective

    209:   Input Parameter:
    210: . viewer  - The PetscViewer

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

    215:   Level: advanced

    217: .seealso: PetscViewerVUGetVecSeen()
    218: @*/
    219: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
    220: {
    221:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

    225:   *vecSeen = vu->vecSeen;
    226:   return 0;
    227: }

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

    232:   Not Collective

    234:   Input Parameters:
    235: + viewer - The PetscViewer
    236: - format - The format string

    238:   Level: intermediate

    240: .seealso: PetscViewerVUFlushDeferred()
    241: @*/
    242: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
    243: {
    244:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
    245:   va_list        Argp;
    246:   size_t         fullLength;
    247:   PrintfQueue    next;

    249:   PetscNew(&next);
    250:   if (vu->queue) {
    251:     vu->queue->next = next;
    252:     vu->queue       = next;
    253:     vu->queue->next = NULL;
    254:   } else {
    255:     vu->queueBase   = vu->queue = next;
    256:   }
    257:   vu->queueLength++;

    259:   va_start(Argp, format);
    260:   PetscArrayzero(next->string,QUEUESTRINGSIZE);
    261:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
    262:   va_end(Argp);
    263:   return 0;
    264: }

    266: /*@C
    267:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

    269:   Not Collective

    271:   Input Parameter:
    272: . viewer - The PetscViewer

    274:   Level: intermediate

    276: .seealso: PetscViewerVUPrintDeferred()
    277: @*/
    278: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
    279: {
    280:   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
    281:   PrintfQueue    next = vu->queueBase;
    282:   PrintfQueue    previous;
    283:   int            i;

    285:   for (i = 0; i < vu->queueLength; i++) {
    286:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
    287:     previous = next;
    288:     next     = next->next;
    289:     PetscFree(previous);
    290:   }
    291:   vu->queue       = NULL;
    292:   vu->queueLength = 0;
    293:   return 0;
    294: }