Actual source code: petscvu.c

      1: #define PETSC_DLL

     3:  #include src/sys/src/viewer/viewerimpl.h
      4: #include <stdarg.h>
      5: #include "petscfix.h"

      7: #define QUEUESTRINGSIZE 1024

      9: typedef struct _PrintfQueue *PrintfQueue;
     10: struct _PrintfQueue {
     11:   char        string[QUEUESTRINGSIZE];
     12:   PrintfQueue next;
     13: };

     15: typedef struct {
     16:   FILE          *fd;
     17:   PetscFileMode mode;     /* The mode in which to open the file */
     18:   char          *filename;
     19:   PetscTruth    vecSeen;  /* The flag indicating whether any vector has been viewed so far */
     20:   PrintfQueue   queue, queueBase;
     21:   int           queueLength;
     22: } PetscViewer_VU;

     26: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
     27: {
     28:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

     32:   if (vu->vecSeen) {
     33:     PetscViewerVUPrintDeferred(viewer, "};\n\n");
     34:   }
     35:   PetscViewerVUFlushDeferred(viewer);
     36:   PetscFClose(viewer->comm, vu->fd);
     37:   PetscStrfree(vu->filename);
     38:   PetscFree(vu);
     39:   return(0);
     40: }

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

     51:   MPI_Comm_rank(viewer->comm, &rank);
     52:   if (!rank) fflush(vu->fd);
     53:   return(0);
     54: }

     59: PetscErrorCode PETSC_DLLEXPORT PetscViewerGetFilename_VU(PetscViewer viewer, char **name)
     60: {
     61:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

     64:   *name = vu->filename;
     65:   return(0);
     66: }

     72: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename_VU(PetscViewer viewer, const char name[])
     73: {
     74:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
     75:   char           fname[PETSC_MAX_PATH_LEN];
     76:   int            rank;

     80:   if (!name) return(0);
     81:   MPI_Comm_rank(viewer->comm, &rank);
     82:   if (rank != 0) return(0);
     83:   PetscStrallocpy(name, &vu->filename);
     84:   PetscFixFilename(name, fname);
     85:   switch(vu->mode) {
     86:   case FILE_MODE_READ:
     87:     vu->fd = fopen(fname, "r");
     88:     break;
     89:   case FILE_MODE_WRITE:
     90:     vu->fd = fopen(fname, "w");
     91:     break;
     92:   case FILE_MODE_APPEND:
     93:     vu->fd = fopen(fname, "a");
     94:     break;
     95:   case FILE_MODE_UPDATE:
     96:     vu->fd = fopen(fname, "r+");
     97:     if (!vu->fd) {
     98:       vu->fd = fopen(fname, "w+");
     99:     }
    100:     break;
    101:   case FILE_MODE_APPEND_UPDATE:
    102:     /* I really want a file which is opened at the end for updating,
    103:        not a+, which opens at the beginning, but makes writes at the end.
    104:     */
    105:     vu->fd = fopen(fname, "r+");
    106:     if (!vu->fd) {
    107:       vu->fd = fopen(fname, "w+");
    108:     } else {
    109:       fseek(vu->fd, 0, SEEK_END);
    110:     }
    111:     break;
    112:   default:
    113:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
    114:   }

    116:   if (!vu->fd) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
    117: #if defined(PETSC_USE_LOG)
    118:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
    119: #endif

    121:   return(0);
    122: }

    128: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_VU(PetscViewer viewer)
    129: {
    130:   PetscViewer_VU *vu;

    134:   PetscNew(PetscViewer_VU, &vu);
    135:   viewer->data = (void*) vu;

    137:   viewer->ops->destroy          = PetscViewerDestroy_VU;
    138:   viewer->ops->flush            = PetscViewerFlush_VU;
    139:   viewer->ops->getsingleton     = PETSC_NULL;
    140:   viewer->ops->restoresingleton = PETSC_NULL;
    141:   viewer->format                = PETSC_VIEWER_ASCII_DEFAULT;
    142:   viewer->iformat               = 0;

    144:   vu->fd          = PETSC_NULL;
    145:   vu->mode        = FILE_MODE_WRITE;
    146:   vu->filename    = PETSC_NULL;
    147:   vu->vecSeen     = PETSC_FALSE;
    148:   vu->queue       = PETSC_NULL;
    149:   vu->queueBase   = PETSC_NULL;
    150:   vu->queueLength = 0;

    152:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerSetFilename_C", "PetscViewerSetFilename_VU",
    153:                                            PetscViewerSetFilename_VU);
    154:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerGetFilename_C", "PetscViewerGetFilename_VU",
    155:                                            PetscViewerGetFilename_VU);

    157:   return(0);
    158: }

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

    166:   Not Collective

    168:   Input Parameter:
    169: . viewer - The PetscViewer

    171:   Output Parameter:
    172: . fd     - The file pointer

    174:   Level: intermediate

    176:   Concepts: PetscViewer^file pointer
    177:   Concepts: file pointer^getting from PetscViewer

    179: .seealso: PetscViewerASCIIGetPointer()
    180: @*/
    181: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
    182: {
    183:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

    188:   *fd = vu->fd;
    189:   return(0);
    190: }

    194: /*@C
    195:   PetscViewerVUSetMode - Sets the mode in which to open the file.

    197:   Not Collective

    199:   Input Parameters:
    200: + viewer - The PetscViewer
    201: - mode   - The file mode

    203:   Level: intermediate

    205: .keywords: Viewer, file, get, pointer
    206: .seealso: PetscViewerASCIISetMode()
    207: @*/
    208: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
    209: {
    210:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

    213:   vu->mode = mode;
    214:   return(0);
    215: }

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

    223:   Not Collective

    225:   Input Parameters:
    226: + viewer  - The PetscViewer
    227: - vecSeen - The flag which indicates whether we have viewed a vector

    229:   Level: advanced

    231: .keywords: Viewer, Vec
    232: .seealso: PetscViewerVUGetVecSeen()
    233: @*/
    234: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
    235: {
    236:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

    239:   vu->vecSeen = vecSeen;
    240:   return(0);
    241: }

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

    249:   Not Collective

    251:   Input Parameter:
    252: . viewer  - The PetscViewer

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

    257:   Level: advanced

    259: .keywords: Viewer, Vec
    260: .seealso: PetscViewerVUGetVecSeen()
    261: @*/
    262: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
    263: {
    264:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

    269:   *vecSeen = vu->vecSeen;
    270:   return(0);
    271: }

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

    278:   Not Collective

    280:   Input Parameters:
    281: + viewer - The PetscViewer
    282: - format - The format string

    284:   Level: intermediate

    286: .keywords: Viewer, print, deferred
    287: .seealso: PetscViewerVUFlushDeferred()
    288: @*/
    289: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
    290: {
    291:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
    292:   va_list        Argp;
    293:   PrintfQueue    next;

    297:   PetscNew(struct _PrintfQueue, &next);
    298:   if (vu->queue) {
    299:     vu->queue->next = next;
    300:     vu->queue       = next;
    301:     vu->queue->next = PETSC_NULL;
    302:   } else {
    303:     vu->queueBase   = vu->queue = next;
    304:   }
    305:   vu->queueLength++;

    307:   va_start(Argp, format);
    308:   PetscMemzero(next->string,QUEUESTRINGSIZE);
    309:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format, Argp);
    310:   va_end(Argp);
    311:   return(0);
    312: }

    316: /*@C
    317:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

    319:   Not Collective

    321:   Input Parameter:
    322: + viewer - The PetscViewer

    324:   Level: intermediate

    326: .keywords: Viewer, flush, deferred
    327: .seealso: PetscViewerVUPrintDeferred()
    328: @*/
    329: PetscErrorCode PETSC_DLLEXPORT PetscViewerVUFlushDeferred(PetscViewer viewer)
    330: {
    331:   PetscViewer_VU *vu   = (PetscViewer_VU *) viewer->data;
    332:   PrintfQueue    next = vu->queueBase;
    333:   PrintfQueue    previous;
    334:   int            i;

    338:   for(i = 0; i < vu->queueLength; i++) {
    339:     PetscFPrintf(viewer->comm, vu->fd, "%s", next->string);
    340:     previous = next;
    341:     next     = next->next;
    342:     PetscFree(previous);
    343:   }
    344:   vu->queue       = PETSC_NULL;
    345:   vu->queueLength = 0;
    346:   return(0);
    347: }