Date: 2026-03-31T05:46:38+00:00

Actual source code: isio.c

      1: #include <petscis.h>
      2: #include <petsc/private/isimpl.h>
      3: #include <petsc/private/viewerimpl.h>
      4: #include <petsclayouthdf5.h>

      6: PetscErrorCode ISView_Binary(IS is, PetscViewer viewer)
      7: {
      8:   PetscBool       skipHeader;
      9:   PetscLayout     map;
     10:   PetscInt        tr[2], n, s, N;
     11:   const PetscInt *iarray;

     13:   PetscFunctionBegin;
     14:   PetscCall(PetscViewerSetUp(viewer));
     15:   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));

     17:   PetscCall(ISGetLayout(is, &map));
     18:   PetscCall(PetscLayoutGetLocalSize(map, &n));
     19:   PetscCall(PetscLayoutGetRange(map, &s, NULL));
     20:   PetscCall(PetscLayoutGetSize(map, &N));

     22:   /* write IS header */
     23:   tr[0] = IS_FILE_CLASSID;
     24:   tr[1] = N;
     25:   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, tr, 2, PETSC_INT));

     27:   /* write IS indices */
     28:   PetscCall(ISGetIndices(is, &iarray));
     29:   PetscCall(PetscViewerBinaryWriteAll(viewer, iarray, n, s, N, PETSC_INT));
     30:   PetscCall(ISRestoreIndices(is, &iarray));
     31:   PetscFunctionReturn(PETSC_SUCCESS);
     32: }

     34: #if defined(PETSC_HAVE_HDF5)
     35: /*
     36:      This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. That is properly casting with
     37:    checks back and forth between the two types of variables.
     38: */
     39: static PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer)
     40: {
     41:   PetscInt   *ind;
     42:   const char *isname;

     44:   PetscFunctionBegin;
     45:   PetscCheck(((PetscObject)is)->name, PetscObjectComm((PetscObject)is), PETSC_ERR_SUP, "IS name must be given using PetscObjectSetName() before ISLoad() since HDF5 can store multiple objects in a single file");
     46:   PetscCall(PetscObjectGetName((PetscObject)is, &isname));
     47:   #if defined(PETSC_USE_64BIT_INDICES)
     48:   PetscCall(PetscViewerHDF5Load(viewer, isname, is->map, H5T_NATIVE_LLONG, (void **)&ind));
     49:   #else
     50:   PetscCall(PetscViewerHDF5Load(viewer, isname, is->map, H5T_NATIVE_INT, (void **)&ind));
     51:   #endif
     52:   PetscCall(ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER));
     53:   PetscCall(PetscInfo(is, "Read IS object with name %s of size %" PetscInt_FMT ":%" PetscInt_FMT "\n", isname, is->map->n, is->map->N));
     54:   PetscFunctionReturn(PETSC_SUCCESS);
     55: }
     56: #endif

     58: static PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer)
     59: {
     60:   PetscBool   isgeneral, skipHeader;
     61:   PetscInt    tr[2], rows, N, n, s, *idx;
     62:   PetscLayout map;

     64:   PetscFunctionBegin;
     65:   PetscCall(PetscObjectTypeCompare((PetscObject)is, ISGENERAL, &isgeneral));
     66:   PetscCheck(isgeneral, PetscObjectComm((PetscObject)is), PETSC_ERR_ARG_INCOMP, "IS must be of type ISGENERAL to load into it");
     67:   PetscCall(PetscViewerSetUp(viewer));
     68:   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));

     70:   PetscCall(ISGetLayout(is, &map));
     71:   PetscCall(PetscLayoutGetSize(map, &N));

     73:   /* read IS header */
     74:   if (!skipHeader) {
     75:     PetscCall(PetscViewerBinaryRead(viewer, tr, 2, NULL, PETSC_INT));
     76:     PetscCheck(tr[0] == IS_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not an IS next in file");
     77:     PetscCheck(tr[1] >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "IS size (%" PetscInt_FMT ") in file is negative", tr[1]);
     78:     PetscCheck(N < 0 || N == tr[1], PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "IS in file different size (%" PetscInt_FMT ") than input IS (%" PetscInt_FMT ")", tr[1], N);
     79:     rows = tr[1];
     80:   } else {
     81:     PetscCheck(N >= 0, PETSC_COMM_SELF, PETSC_ERR_USER, "IS binary file header was skipped, thus the user must specify the global size of input IS");
     82:     rows = N;
     83:   }

     85:   /* set IS size if not already set */
     86:   if (N < 0) PetscCall(PetscLayoutSetSize(map, rows));
     87:   PetscCall(PetscLayoutSetUp(map));

     89:   /* get IS sizes and check global size */
     90:   PetscCall(PetscLayoutGetSize(map, &N));
     91:   PetscCall(PetscLayoutGetLocalSize(map, &n));
     92:   PetscCall(PetscLayoutGetRange(map, &s, NULL));
     93:   PetscCheck(N == rows, PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "IS in file different size (%" PetscInt_FMT ") than input IS (%" PetscInt_FMT ")", rows, N);

     95:   /* read IS indices */
     96:   PetscCall(PetscMalloc1(n, &idx));
     97:   PetscCall(PetscViewerBinaryReadAll(viewer, idx, n, s, N, PETSC_INT));
     98:   PetscCall(ISGeneralSetIndices(is, n, idx, PETSC_OWN_POINTER));
     99:   PetscFunctionReturn(PETSC_SUCCESS);
    100: }

    102: PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
    103: {
    104:   PetscBool isbinary, ishdf5;

    106:   PetscFunctionBegin;
    107:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
    108:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
    109:   if (isbinary) {
    110:     PetscCall(ISLoad_Binary(is, viewer));
    111:   } else if (ishdf5) {
    112: #if defined(PETSC_HAVE_HDF5)
    113:     PetscCall(ISLoad_HDF5(is, viewer));
    114: #endif
    115:   }
    116:   PetscFunctionReturn(PETSC_SUCCESS);
    117: }