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) {
     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

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

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

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

    200:   Not Collective

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

    206:   Level: advanced

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

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

    219: /*@C
    220:   PetscViewerVUGetVecSeen - Gets 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 Parameter:
    226: . viewer  - The PetscViewer

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

    231:   Level: advanced

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

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

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

    249:   Not Collective

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

    255:   Level: intermediate

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

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

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

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

    288:   Not Collective

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

    293:   Level: intermediate

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

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