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. These means 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:   hid_t       inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
 42:   PetscInt   *ind;
 43:   const char *isname;

 45:   PetscFunctionBegin;
 46:   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");
 47:   #if defined(PETSC_USE_64BIT_INDICES)
 48:   inttype = H5T_NATIVE_LLONG;
 49:   #else
 50:   inttype = H5T_NATIVE_INT;
 51:   #endif
 52:   PetscCall(PetscObjectGetName((PetscObject)is, &isname));
 53:   PetscCall(PetscViewerHDF5Load(viewer, isname, is->map, inttype, (void **)&ind));
 54:   PetscCall(ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER));
 55:   PetscCall(PetscInfo(is, "Read IS object with name %s of size %" PetscInt_FMT ":%" PetscInt_FMT "\n", isname, is->map->n, is->map->N));
 56:   PetscFunctionReturn(PETSC_SUCCESS);
 57: }
 58: #endif

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

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

 72:   PetscCall(ISGetLayout(is, &map));
 73:   PetscCall(PetscLayoutGetSize(map, &N));

 75:   /* read IS header */
 76:   if (!skipHeader) {
 77:     PetscCall(PetscViewerBinaryRead(viewer, tr, 2, NULL, PETSC_INT));
 78:     PetscCheck(tr[0] == IS_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not an IS next in file");
 79:     PetscCheck(tr[1] >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "IS size (%" PetscInt_FMT ") in file is negative", tr[1]);
 80:     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);
 81:     rows = tr[1];
 82:   } else {
 83:     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");
 84:     rows = N;
 85:   }

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

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

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

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

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