xref: /petsc/src/vec/is/utils/isio.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
1 #include <petscis.h> /*I  "petscis.h"  I*/
2 #include <petsc/private/isimpl.h>
3 #include <petsc/private/viewerimpl.h>
4 #include <petsclayouthdf5.h>
5 
6 PetscErrorCode ISView_Binary(IS is, PetscViewer viewer) {
7   PetscBool       skipHeader;
8   PetscLayout     map;
9   PetscInt        tr[2], n, s, N;
10   const PetscInt *iarray;
11 
12   PetscFunctionBegin;
13   PetscCall(PetscViewerSetUp(viewer));
14   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
15 
16   PetscCall(ISGetLayout(is, &map));
17   PetscCall(PetscLayoutGetLocalSize(map, &n));
18   PetscCall(PetscLayoutGetRange(map, &s, NULL));
19   PetscCall(PetscLayoutGetSize(map, &N));
20 
21   /* write IS header */
22   tr[0] = IS_FILE_CLASSID;
23   tr[1] = N;
24   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, tr, 2, PETSC_INT));
25 
26   /* write IS indices */
27   PetscCall(ISGetIndices(is, &iarray));
28   PetscCall(PetscViewerBinaryWriteAll(viewer, iarray, n, s, N, PETSC_INT));
29   PetscCall(ISRestoreIndices(is, &iarray));
30   PetscFunctionReturn(0);
31 }
32 
33 #if defined(PETSC_HAVE_HDF5)
34 /*
35      This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. These means properly casting with
36    checks back and forth between the two types of variables.
37 */
38 PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer) {
39   hid_t       inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
40   PetscInt   *ind;
41   const char *isname;
42 
43   PetscFunctionBegin;
44   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");
45 #if defined(PETSC_USE_64BIT_INDICES)
46   inttype = H5T_NATIVE_LLONG;
47 #else
48   inttype = H5T_NATIVE_INT;
49 #endif
50   PetscCall(PetscObjectGetName((PetscObject)is, &isname));
51   PetscCall(PetscViewerHDF5Load(viewer, isname, is->map, inttype, (void **)&ind));
52   PetscCall(ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER));
53   PetscFunctionReturn(0);
54 }
55 #endif
56 
57 PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer) {
58   PetscBool   isgeneral, skipHeader;
59   PetscInt    tr[2], rows, N, n, s, *idx;
60   PetscLayout map;
61 
62   PetscFunctionBegin;
63   PetscCall(PetscObjectTypeCompare((PetscObject)is, ISGENERAL, &isgeneral));
64   PetscCheck(isgeneral, PetscObjectComm((PetscObject)is), PETSC_ERR_ARG_INCOMP, "IS must be of type ISGENERAL to load into it");
65   PetscCall(PetscViewerSetUp(viewer));
66   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
67 
68   PetscCall(ISGetLayout(is, &map));
69   PetscCall(PetscLayoutGetSize(map, &N));
70 
71   /* read IS header */
72   if (!skipHeader) {
73     PetscCall(PetscViewerBinaryRead(viewer, tr, 2, NULL, PETSC_INT));
74     PetscCheck(tr[0] == IS_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not an IS next in file");
75     PetscCheck(tr[1] >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "IS size (%" PetscInt_FMT ") in file is negative", tr[1]);
76     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);
77     rows = tr[1];
78   } else {
79     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");
80     rows = N;
81   }
82 
83   /* set IS size if not already set */
84   if (N < 0) PetscCall(PetscLayoutSetSize(map, rows));
85   PetscCall(PetscLayoutSetUp(map));
86 
87   /* get IS sizes and check global size */
88   PetscCall(PetscLayoutGetSize(map, &N));
89   PetscCall(PetscLayoutGetLocalSize(map, &n));
90   PetscCall(PetscLayoutGetRange(map, &s, NULL));
91   PetscCheck(N == rows, PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "IS in file different size (%" PetscInt_FMT ") than input IS (%" PetscInt_FMT ")", rows, N);
92 
93   /* read IS indices */
94   PetscCall(PetscMalloc1(n, &idx));
95   PetscCall(PetscViewerBinaryReadAll(viewer, idx, n, s, N, PETSC_INT));
96   PetscCall(ISGeneralSetIndices(is, n, idx, PETSC_OWN_POINTER));
97   PetscFunctionReturn(0);
98 }
99 
100 PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer) {
101   PetscBool isbinary, ishdf5;
102 
103   PetscFunctionBegin;
104   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
105   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
106   if (isbinary) {
107     PetscCall(ISLoad_Binary(is, viewer));
108   } else if (ishdf5) {
109 #if defined(PETSC_HAVE_HDF5)
110     PetscCall(ISLoad_HDF5(is, viewer));
111 #endif
112   }
113   PetscFunctionReturn(0);
114 }
115