xref: /petsc/src/vec/is/utils/isio.c (revision 0baf8eba40dbc839082666f9f7396a225d6f663c)
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 {
8   PetscBool       skipHeader;
9   PetscLayout     map;
10   PetscInt        tr[2], n, s, N;
11   const PetscInt *iarray;
12 
13   PetscFunctionBegin;
14   PetscCall(PetscViewerSetUp(viewer));
15   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
16 
17   PetscCall(ISGetLayout(is, &map));
18   PetscCall(PetscLayoutGetLocalSize(map, &n));
19   PetscCall(PetscLayoutGetRange(map, &s, NULL));
20   PetscCall(PetscLayoutGetSize(map, &N));
21 
22   /* write IS header */
23   tr[0] = IS_FILE_CLASSID;
24   tr[1] = N;
25   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, tr, 2, PETSC_INT));
26 
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 }
33 
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;
44 
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
59 
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;
65 
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));
71 
72   PetscCall(ISGetLayout(is, &map));
73   PetscCall(PetscLayoutGetSize(map, &N));
74 
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   }
86 
87   /* set IS size if not already set */
88   if (N < 0) PetscCall(PetscLayoutSetSize(map, rows));
89   PetscCall(PetscLayoutSetUp(map));
90 
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);
96 
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 }
103 
104 PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
105 {
106   PetscBool isbinary, ishdf5;
107 
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 }
120