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
ISView_Binary(IS is,PetscViewer viewer)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. That is properly casting with
37 checks back and forth between the two types of variables.
38 */
ISLoad_HDF5(IS is,PetscViewer viewer)39 static PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer)
40 {
41 PetscInt *ind;
42 const char *isname;
43
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
57
ISLoad_Binary(IS is,PetscViewer viewer)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;
63
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));
69
70 PetscCall(ISGetLayout(is, &map));
71 PetscCall(PetscLayoutGetSize(map, &N));
72
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 }
84
85 /* set IS size if not already set */
86 if (N < 0) PetscCall(PetscLayoutSetSize(map, rows));
87 PetscCall(PetscLayoutSetUp(map));
88
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);
94
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 }
101
ISLoad_Default(IS is,PetscViewer viewer)102 PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
103 {
104 PetscBool isbinary, ishdf5;
105
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 }
118