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

Actual source code: filev.c

      2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>

      4: #define QUEUESTRINGSIZE 8192

      6: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
      7: {
      8:   PetscErrorCode    ierr;
      9:   PetscMPIInt       rank;
     10:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     11:   int               err;

     14:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
     15:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
     16:   if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
     17:     if (vascii->fd && vascii->closefile) {
     18:       err = fclose(vascii->fd);
     19:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
     20:     }
     21:     if (vascii->storecompressed) {
     22:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
     23:       FILE *fp;
     24:       PetscStrncpy(par,"gzip ",sizeof(par));
     25:       PetscStrlcat(par,vascii->filename,sizeof(par));
     26: #if defined(PETSC_HAVE_POPEN)
     27:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
     28:       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
     29:       PetscPClose(PETSC_COMM_SELF,fp);
     30: #else
     31:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
     32: #endif
     33:     }
     34:   }
     35:   PetscFree(vascii->filename);
     36:   return(0);
     37: }

     39: /* ----------------------------------------------------------------------*/
     40: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
     41: {
     42:   PetscErrorCode    ierr;
     43:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     44:   PetscViewerLink   *vlink;
     45:   PetscBool         flg;

     48:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
     49:   PetscViewerFileClose_ASCII(viewer);
     50:   PetscFree(vascii);

     52:   /* remove the viewer from the list in the MPI Communicator */
     53:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
     54:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
     55:   }

     57:   MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
     58:   if (flg) {
     59:     if (vlink && vlink->viewer == viewer) {
     60:       if (vlink->next) {
     61:         MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
     62:       } else {
     63:         MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
     64:       }
     65:       PetscFree(vlink);
     66:     } else {
     67:       while (vlink && vlink->next) {
     68:         if (vlink->next->viewer == viewer) {
     69:           PetscViewerLink *nv = vlink->next;
     70:           vlink->next = vlink->next->next;
     71:           PetscFree(nv);
     72:         }
     73:         vlink = vlink->next;
     74:       }
     75:     }
     76:   }

     78:   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
     79:     PetscViewer aviewer;
     80:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     81:     if (flg && aviewer == viewer) {
     82:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
     83:     }
     84:   }
     85:   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
     86:     PetscViewer aviewer;
     87:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     88:     if (flg && aviewer == viewer) {
     89:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
     90:     }
     91:   }
     92:   return(0);
     93: }

     95: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
     96: {
     97:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     98:   PetscErrorCode    ierr;

    101:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
    102:   return(0);
    103: }

    105: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
    106: {
    107:   PetscErrorCode    ierr;
    108:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    109:   int               err;
    110:   MPI_Comm          comm;
    111:   PetscMPIInt       rank,size;
    112:   FILE              *fd = vascii->fd;

    115:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    116:   PetscObjectGetComm((PetscObject)viewer,&comm);
    117:   MPI_Comm_rank(comm,&rank);
    118:   MPI_Comm_size(comm,&size);

    120:   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
    121:     err = fflush(vascii->fd);
    122:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
    123:   }

    125:   if (vascii->allowsynchronized) {
    126:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
    127:     char          *message;
    128:     MPI_Status    status;

    130:     PetscCommDuplicate(comm,&comm,&tag);

    132:     /* First processor waits for messages from all other processors */
    133:     if (rank == 0) {
    134:       /* flush my own messages that I may have queued up */
    135:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    136:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    137:         if (!vascii->bviewer) {
    138:           PetscFPrintf(comm,fd,"%s",next->string);
    139:         } else {
    140:           PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
    141:         }
    142:         previous = next;
    143:         next     = next->next;
    144:         PetscFree(previous->string);
    145:         PetscFree(previous);
    146:       }
    147:       vascii->petsc_printfqueue       = NULL;
    148:       vascii->petsc_printfqueuelength = 0;
    149:       for (i=1; i<size; i++) {
    150:         /* to prevent a flood of messages to process zero, request each message separately */
    151:         MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
    152:         MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
    153:         for (j=0; j<n; j++) {
    154:           PetscMPIInt size = 0;

    156:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
    157:           PetscMalloc1(size, &message);
    158:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
    159:           if (!vascii->bviewer) {
    160:             PetscFPrintf(comm,fd,"%s",message);
    161:           } else {
    162:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
    163:           }
    164:           PetscFree(message);
    165:         }
    166:       }
    167:     } else { /* other processors send queue to processor 0 */
    168:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

    170:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
    171:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
    172:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    173:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
    174:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
    175:         previous = next;
    176:         next     = next->next;
    177:         PetscFree(previous->string);
    178:         PetscFree(previous);
    179:       }
    180:       vascii->petsc_printfqueue       = NULL;
    181:       vascii->petsc_printfqueuelength = 0;
    182:     }
    183:     PetscCommDestroy(&comm);
    184:   }
    185:   return(0);
    186: }

    188: /*@C
    189:     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.

    191:     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer

    193:     Input Parameter:
    194: .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()

    196:     Output Parameter:
    197: .    fd - file pointer

    199:     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer

    201:     Level: intermediate

    203:     Fortran Note:
    204:     This routine is not supported in Fortran.

    206: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    207:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    208: @*/
    209: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    210: {
    211:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    214:   *fd = vascii->fd;
    215:   return(0);
    216: }

    218: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
    219: {
    220:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    223:   *mode = vascii->mode;
    224:   return(0);
    225: }

    227: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
    228: {
    229:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    232:   vascii->mode = mode;
    233:   return(0);
    234: }

    236: /*
    237:    If petsc_history is on, then all Petsc*Printf() results are saved
    238:    if the appropriate (usually .petschistory) file.
    239: */
    240: PETSC_INTERN FILE *petsc_history;

    242: /*@
    243:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

    245:     Not Collective, but only first processor in set has any effect

    247:     Input Parameters:
    248: +    viewer - obtained with PetscViewerASCIIOpen()
    249: -    tabs - number of tabs

    251:     Level: developer

    253:     Fortran Note:
    254:     This routine is not supported in Fortran.

    256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
    257:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    258:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    259: @*/
    260: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
    261: {
    262:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    263:   PetscBool         iascii;
    264:   PetscErrorCode    ierr;

    268:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    269:   if (iascii) ascii->tab = tabs;
    270:   return(0);
    271: }

    273: /*@
    274:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

    276:     Not Collective, meaningful on first processor only.

    278:     Input Parameters:
    279: .    viewer - obtained with PetscViewerASCIIOpen()

    281:     Output Parameters:
    282: .    tabs - number of tabs

    284:     Level: developer

    286:     Fortran Note:
    287:     This routine is not supported in Fortran.

    289: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
    290:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    291:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    292: @*/
    293: PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
    294: {
    295:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    296:   PetscBool         iascii;
    297:   PetscErrorCode    ierr;

    301:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    302:   if (iascii && tabs) *tabs = ascii->tab;
    303:   return(0);
    304: }

    306: /*@
    307:     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing

    309:     Not Collective, but only first processor in set has any effect

    311:     Input Parameters:
    312: +    viewer - obtained with PetscViewerASCIIOpen()
    313: -    tabs - number of tabs

    315:     Level: developer

    317:     Fortran Note:
    318:     This routine is not supported in Fortran.

    320: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    321:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    322:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    323: @*/
    324: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
    325: {
    326:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    327:   PetscBool         iascii;
    328:   PetscErrorCode    ierr;

    332:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    333:   if (iascii) ascii->tab += tabs;
    334:   return(0);
    335: }

    337: /*@
    338:     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing

    340:     Not Collective, but only first processor in set has any effect

    342:     Input Parameters:
    343: +    viewer - obtained with PetscViewerASCIIOpen()
    344: -    tabs - number of tabs

    346:     Level: developer

    348:     Fortran Note:
    349:     This routine is not supported in Fortran.

    351: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    352:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    353:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    354: @*/
    355: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
    356: {
    357:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    358:   PetscBool         iascii;
    359:   PetscErrorCode    ierr;

    363:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    364:   if (iascii) ascii->tab -= tabs;
    365:   return(0);
    366: }

    368: /*@C
    369:     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

    371:     Collective on PetscViewer

    373:     Input Parameters:
    374: .    viewer - obtained with PetscViewerASCIIOpen()

    376:     Level: intermediate

    378:     Notes:
    379:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

    381: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
    382:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    383:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    384: @*/
    385: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
    386: {
    387:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    388:   PetscBool         iascii;
    389:   PetscErrorCode    ierr;

    393:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    394:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    395:   if (iascii) ascii->allowsynchronized++;
    396:   return(0);
    397: }

    399: /*@C
    400:     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer

    402:     Collective on PetscViewer

    404:     Input Parameters:
    405: .    viewer - obtained with PetscViewerASCIIOpen()

    407:     Level: intermediate

    409:     Notes:
    410:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

    412: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
    413:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    414:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    415: @*/
    416: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
    417: {
    418:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    419:   PetscBool         iascii;
    420:   PetscErrorCode    ierr;

    424:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    425:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    426:   if (iascii) {
    427:     ascii->allowsynchronized--;
    428:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
    429:   }
    430:   return(0);
    431: }

    433: /*@C
    434:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    435:      lines are tabbed.

    437:     Not Collective, but only first processor in set has any effect

    439:     Input Parameters:
    440: .    viewer - obtained with PetscViewerASCIIOpen()

    442:     Level: developer

    444:     Fortran Note:
    445:     This routine is not supported in Fortran.

    447: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    448:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    449:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    450: @*/
    451: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
    452: {
    453:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    454:   PetscBool         iascii;
    455:   PetscErrorCode    ierr;

    459:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    460:   if (iascii) ascii->tab++;
    461:   return(0);
    462: }

    464: /*@C
    465:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    466:      lines are tabbed.

    468:     Not Collective, but only first processor in set has any effect

    470:     Input Parameters:
    471: .    viewer - obtained with PetscViewerASCIIOpen()

    473:     Level: developer

    475:     Fortran Note:
    476:     This routine is not supported in Fortran.

    478: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    479:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    480:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    481: @*/
    482: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
    483: {
    484:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    485:   PetscErrorCode    ierr;
    486:   PetscBool         iascii;

    490:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    491:   if (iascii) {
    492:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    493:     ascii->tab--;
    494:   }
    495:   return(0);
    496: }

    498: /*@
    499:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

    501:     Not Collective, but only first processor in set has any effect

    503:     Input Parameters:
    504: +    viewer - obtained with PetscViewerASCIIOpen()
    505: -    flg - PETSC_TRUE or PETSC_FALSE

    507:     Level: developer

    509:     Fortran Note:
    510:     This routine is not supported in Fortran.

    512: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    513:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
    514:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    515: @*/
    516: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
    517: {
    518:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    519:   PetscBool         iascii;
    520:   PetscErrorCode    ierr;

    524:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    525:   if (iascii) {
    526:     if (flg) ascii->tab = ascii->tab_store;
    527:     else {
    528:       ascii->tab_store = ascii->tab;
    529:       ascii->tab       = 0;
    530:     }
    531:   }
    532:   return(0);
    533: }

    535: /* ----------------------------------------------------------------------- */

    537: /*@C
    538:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    539:     processor in the PetscViewer

    541:     Not Collective, but only first processor in set has any effect

    543:     Input Parameters:
    544: +    viewer - obtained with PetscViewerASCIIOpen()
    545: -    format - the usual printf() format string

    547:     Level: developer

    549:     Fortran Note:
    550:     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
    551:     That is, you can only pass a single character string from Fortran.

    553: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    554:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    555:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
    556: @*/
    557: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    558: {
    559:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    560:   PetscMPIInt       rank;
    561:   PetscInt          tab,intab = ascii->tab;
    562:   PetscErrorCode    ierr;
    563:   FILE              *fd = ascii->fd;
    564:   PetscBool         iascii;
    565:   int               err;

    569:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    571:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    572:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    573:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    574:   if (rank) return(0);

    576:   if (ascii->bviewer) { /* pass string up to parent viewer */
    577:     char        *string;
    578:     va_list     Argp;
    579:     size_t      fullLength;

    581:     PetscCalloc1(QUEUESTRINGSIZE, &string);
    582:     va_start(Argp,format);
    583:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
    584:     va_end(Argp);
    585:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
    586:     PetscFree(string);
    587:   } else { /* write directly to file */
    588:     va_list Argp;
    589:     /* flush my own messages that I may have queued up */
    590:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
    591:     PetscInt    i;
    592:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
    593:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
    594:       previous = next;
    595:       next     = next->next;
    596:       PetscFree(previous->string);
    597:       PetscFree(previous);
    598:     }
    599:     ascii->petsc_printfqueue       = NULL;
    600:     ascii->petsc_printfqueuelength = 0;
    601:     tab = intab;
    602:     while (tab--) {
    603:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    604:     }

    606:     va_start(Argp,format);
    607:     (*PetscVFPrintf)(fd,format,Argp);
    608:     err  = fflush(fd);
    609:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    610:     if (petsc_history) {
    611:       va_start(Argp,format);
    612:       tab = intab;
    613:       while (tab--) {
    614:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
    615:       }
    616:       (*PetscVFPrintf)(petsc_history,format,Argp);
    617:       err  = fflush(petsc_history);
    618:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    619:     }
    620:     va_end(Argp);
    621:   }
    622:   return(0);
    623: }

    625: /*@C
    626:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

    628:     Collective on PetscViewer

    630:   Input Parameters:
    631: +  viewer - the PetscViewer; either ASCII or binary
    632: -  name - the name of the file it should use

    634:     Level: advanced

    636: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    637:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    639: @*/
    640: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
    641: {
    643:   char           filename[PETSC_MAX_PATH_LEN];

    648:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
    649:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
    650:   return(0);
    651: }

    653: /*@C
    654:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

    656:     Not Collective

    658:   Input Parameter:
    659: .  viewer - the PetscViewer; either ASCII or binary

    661:   Output Parameter:
    662: .  name - the name of the file it is using

    664:     Level: advanced

    666: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()

    668: @*/
    669: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
    670: {

    676:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
    677:   return(0);
    678: }

    680: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
    681: {
    682:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    685:   *name = vascii->filename;
    686:   return(0);
    687: }

    689: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
    690: {
    691:   PetscErrorCode    ierr;
    692:   size_t            len;
    693:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    694:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    695:   PetscBool         isstderr,isstdout;
    696:   PetscMPIInt       rank;

    699:   PetscViewerFileClose_ASCII(viewer);
    700:   if (!name) return(0);
    701:   PetscStrallocpy(name,&vascii->filename);

    703:   /* Is this file to be compressed */
    704:   vascii->storecompressed = PETSC_FALSE;

    706:   PetscStrstr(vascii->filename,".gz",&gz);
    707:   if (gz) {
    708:     PetscStrlen(gz,&len);
    709:     if (len == 3) {
    710:       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
    711:       *gz = 0;
    712:       vascii->storecompressed = PETSC_TRUE;
    713:     }
    714:   }
    715:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    716:   if (rank == 0) {
    717:     PetscStrcmp(name,"stderr",&isstderr);
    718:     PetscStrcmp(name,"stdout",&isstdout);
    719:     /* empty filename means stdout */
    720:     if (name[0] == 0)  isstdout = PETSC_TRUE;
    721:     if (isstderr)      vascii->fd = PETSC_STDERR;
    722:     else if (isstdout) vascii->fd = PETSC_STDOUT;
    723:     else {

    725:       PetscFixFilename(name,fname);
    726:       switch (vascii->mode) {
    727:       case FILE_MODE_READ:
    728:         vascii->fd = fopen(fname,"r");
    729:         break;
    730:       case FILE_MODE_WRITE:
    731:         vascii->fd = fopen(fname,"w");
    732:         break;
    733:       case FILE_MODE_APPEND:
    734:         vascii->fd = fopen(fname,"a");
    735:         break;
    736:       case FILE_MODE_UPDATE:
    737:         vascii->fd = fopen(fname,"r+");
    738:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    739:         break;
    740:       case FILE_MODE_APPEND_UPDATE:
    741:         /* I really want a file which is opened at the end for updating,
    742:            not a+, which opens at the beginning, but makes writes at the end.
    743:         */
    744:         vascii->fd = fopen(fname,"r+");
    745:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    746:         else {
    747:           fseek(vascii->fd, 0, SEEK_END);
    748:         }
    749:         break;
    750:       default:
    751:         SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
    752:       }
    753:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    754:     }
    755:   }
    756: #if defined(PETSC_USE_LOG)
    757:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    758: #endif
    759:   return(0);
    760: }

    762: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    763: {
    764:   PetscErrorCode    ierr;
    765:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

    768:   PetscViewerASCIIPushSynchronized(viewer);
    769:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
    770:   /*
    771:      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
    772:      because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
    773:      (since the count never gets to zero) in some examples this displays information that otherwise would be lost

    775:      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
    776:      PCView_GASM().
    777:   */
    778:   PetscViewerASCIIPushSynchronized(viewer);
    779:   PetscViewerCreate(subcomm,outviewer);
    780:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
    781:   PetscViewerASCIIPushSynchronized(*outviewer);
    782:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    783:   ovascii->fd  = vascii->fd;
    784:   ovascii->tab = vascii->tab;
    785:   ovascii->closefile = PETSC_FALSE;

    787:   vascii->sviewer = *outviewer;
    788:   (*outviewer)->format  = viewer->format;
    789:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    790:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
    791:   return(0);
    792: }

    794: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
    795: {
    796:   PetscErrorCode    ierr;
    797:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

    800:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
    801:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");

    803:   PetscViewerASCIIPopSynchronized(*outviewer);
    804:   ascii->sviewer             = NULL;
    805:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    806:   PetscViewerDestroy(outviewer);
    807:   PetscViewerASCIIPopSynchronized(viewer);
    808:   return(0);
    809: }

    811: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
    812: {
    813:   PetscErrorCode    ierr;
    814:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

    817:   if (ascii->filename) {
    818:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
    819:   }
    820:   return(0);
    821: }

    823: /*MC
    824:    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file

    826: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
    827:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
    828:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    830:   Level: beginner

    832: M*/
    833: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
    834: {
    835:   PetscViewer_ASCII *vascii;
    836:   PetscErrorCode    ierr;

    839:   PetscNewLog(viewer,&vascii);
    840:   viewer->data = (void*)vascii;

    842:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    843:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    844:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
    845:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
    846:   viewer->ops->view             = PetscViewerView_ASCII;
    847:   viewer->ops->read             = PetscViewerASCIIRead;

    849:   /* defaults to stdout unless set with PetscViewerFileSetName() */
    850:   vascii->fd        = PETSC_STDOUT;
    851:   vascii->mode      = FILE_MODE_WRITE;
    852:   vascii->bviewer   = NULL;
    853:   vascii->subviewer = NULL;
    854:   vascii->sviewer   = NULL;
    855:   vascii->tab       = 0;
    856:   vascii->tab_store = 0;
    857:   vascii->filename  = NULL;
    858:   vascii->closefile = PETSC_TRUE;

    860:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
    861:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
    862:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
    863:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
    864:   return(0);
    865: }

    867: /*@C
    868:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    869:     several processors.  Output of the first processor is followed by that of the
    870:     second, etc.

    872:     Not Collective, must call collective PetscViewerFlush() to get the results out

    874:     Input Parameters:
    875: +   viewer - the ASCII PetscViewer
    876: -   format - the usual printf() format string

    878:     Level: intermediate

    880:     Notes:
    881:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
    882:     Then you can do multiple independent calls to this routine.
    883:     The actual synchronized print is then done using PetscViewerFlush().
    884:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
    885:     to conclude the "synchronized session".
    886:     So the typical calling sequence looks like
    887: $ PetscViewerASCIIPushSynchronized(viewer);
    888: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    889: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    890: $ ...
    891: $ PetscViewerFlush(viewer);
    892: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    893: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    894: $ ...
    895: $ PetscViewerFlush(viewer);
    896: $ PetscViewerASCIIPopSynchronized(viewer);

    898:     Fortran Note:
    899:       Can only print a single character* string

    901: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
    902:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    903:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    904: @*/
    905: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    906: {
    907:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    908:   PetscErrorCode    ierr;
    909:   PetscMPIInt       rank;
    910:   PetscInt          tab = vascii->tab;
    911:   MPI_Comm          comm;
    912:   FILE              *fp;
    913:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
    914:   int               err;

    919:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    920:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    921:   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");

    923:   PetscObjectGetComm((PetscObject)viewer,&comm);
    924:   MPI_Comm_rank(comm,&rank);

    926:   if (vascii->bviewer) {
    927:     hasbviewer = PETSC_TRUE;
    928:     if (rank == 0) {
    929:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
    930:       PetscObjectGetComm((PetscObject)viewer,&comm);
    931:       MPI_Comm_rank(comm,&rank);
    932:     }
    933:   }

    935:   fp   = vascii->fd;

    937:   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
    938:     va_list Argp;
    939:     /* flush my own messages that I may have queued up */
    940:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    941:     PetscInt    i;
    942:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    943:       PetscFPrintf(comm,fp,"%s",next->string);
    944:       previous = next;
    945:       next     = next->next;
    946:       PetscFree(previous->string);
    947:       PetscFree(previous);
    948:     }
    949:     vascii->petsc_printfqueue       = NULL;
    950:     vascii->petsc_printfqueuelength = 0;

    952:     while (tab--) {
    953:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
    954:     }

    956:     va_start(Argp,format);
    957:     (*PetscVFPrintf)(fp,format,Argp);
    958:     err  = fflush(fp);
    959:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    960:     if (petsc_history) {
    961:       va_start(Argp,format);
    962:       (*PetscVFPrintf)(petsc_history,format,Argp);
    963:       err  = fflush(petsc_history);
    964:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    965:     }
    966:     va_end(Argp);
    967:   } else { /* other processors add to queue */
    968:     char        *string;
    969:     va_list     Argp;
    970:     size_t      fullLength;
    971:     PrintfQueue next;

    973:     PetscNew(&next);
    974:     if (vascii->petsc_printfqueue) {
    975:       vascii->petsc_printfqueue->next = next;
    976:       vascii->petsc_printfqueue       = next;
    977:     } else {
    978:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
    979:     }
    980:     vascii->petsc_printfqueuelength++;
    981:     next->size = QUEUESTRINGSIZE;
    982:     PetscCalloc1(next->size, &next->string);
    983:     string     = next->string;
    984:     tab       *= 2;
    985:     while (tab--) {
    986:       *string++ = ' ';
    987:     }
    988:     va_start(Argp,format);
    989:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
    990:     va_end(Argp);
    991:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
    992:       PetscFree(next->string);
    993:       next->size = fullLength + 2*vascii->tab;
    994:       PetscCalloc1(next->size, &next->string);
    995:       string     = next->string;
    996:       tab        = 2*vascii->tab;
    997:       while (tab--) {
    998:         *string++ = ' ';
    999:       }
    1000:       va_start(Argp,format);
    1001:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
    1002:       va_end(Argp);
    1003:     }
    1004:   }
    1005:   return(0);
    1006: }

    1008: /*@C
    1009:    PetscViewerASCIIRead - Reads from a ASCII file

    1011:    Only process 0 in the PetscViewer may call this

    1013:    Input Parameters:
    1014: +  viewer - the ascii viewer
    1015: .  data - location to write the data
    1016: .  num - number of items of data to read
    1017: -  datatype - type of data to read

    1019:    Output Parameters:
    1020: .  count - number of items of data actually read, or NULL

    1022:    Level: beginner

    1024: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
    1025:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    1026:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
    1027: @*/
    1028: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
    1029: {
    1030:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    1031:   FILE              *fd = vascii->fd;
    1032:   PetscInt           i;
    1033:   int                ret = 0;
    1034:   PetscMPIInt        rank;
    1035:   PetscErrorCode     ierr;

    1039:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    1040:   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
    1041:   for (i=0; i<num; i++) {
    1042:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
    1043:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
    1044:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
    1045:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
    1046:     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
    1047:     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
    1048:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
    1049:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
    1050: #if defined(PETSC_USE_REAL___FLOAT128)
    1051:     else if (dtype == PETSC___FLOAT128) {
    1052:       double tmp;
    1053:       ret = fscanf(fd, "%lg", &tmp);
    1054:       ((__float128*)data)[i] = tmp;
    1055:     }
    1056: #endif
    1057:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
    1058:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
    1059:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
    1060:   }
    1061:   if (count) *count = i;
    1062:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
    1063:   return(0);
    1064: }