Actual source code: isio.c
petsc-3.6.1 2015-08-06
1: #include <petscis.h> /*I "petscis.h" I*/
2: #include <petsc/private/isimpl.h>
3: #include <petscviewerhdf5.h>
5: #if defined(PETSC_HAVE_HDF5)
8: /*
9: This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. These means properly casting with
10: checks back and forth between the two types of variables.
11: */
12: PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer)
13: {
14: hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
15: hid_t file_id, group, dset_id, filespace, memspace, plist_id;
16: int rdim, dim;
17: hsize_t dims[3], count[3], offset[3];
18: PetscInt n, N, bs, bsInd, lenInd, low, timestep;
19: const PetscInt *ind;
20: const char *isname;
21: PetscErrorCode ierr;
24: PetscViewerHDF5OpenGroup(viewer, &file_id, &group);
25: PetscViewerHDF5GetTimestep(viewer, ×tep);
26: ISGetBlockSize(is, &bs);
27: /* Create the dataset with default properties and close filespace */
28: PetscObjectGetName((PetscObject) is, &isname);
29: #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
30: PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, isname, H5P_DEFAULT));
31: #else
32: PetscStackCallHDF5Return(dset_id,H5Dopen,(group, isname));
33: #endif
34: /* Retrieve the dataspace for the dataset */
35: PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id));
36: dim = 0;
37: if (timestep >= 0) ++dim;
38: ++dim;
39: ++dim;
40: PetscStackCallHDF5Return(rdim,H5Sget_simple_extent_dims,(filespace, dims, NULL));
41: bsInd = rdim-1;
42: lenInd = timestep >= 0 ? 1 : 0;
43: if (rdim != dim) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Dimension of array in file %d not %d as expected",rdim,dim);
44: else if (bs != (PetscInt) dims[bsInd]) {
45: ISSetBlockSize(is, dims[bsInd]);
46: if (ierr) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "Block size %d specified for IS does not match blocksize in file %d",bs,dims[bsInd]);
47: bs = dims[bsInd];
48: }
50: /* Set Vec sizes,blocksize,and type if not already set */
51: ISGetLocalSize(is, &n);
52: ISGetSize(is, &N);
53: if (n < 0 && N < 0) {PetscLayoutSetSize(is->map, dims[lenInd]*bs);}
54: PetscLayoutSetUp(is->map);
55: /* If sizes and type already set,check if the vector global size is correct */
56: ISGetSize(is, &N);
57: if (N/bs != (PetscInt) dims[lenInd]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "IS in file different length (%d) then input vector (%d)", (PetscInt) dims[lenInd], N/bs);
59: /* Each process defines a dataset and reads it from the hyperslab in the file */
60: ISGetLocalSize(is, &n);
61: dim = 0;
62: if (timestep >= 0) {
63: count[dim] = 1;
64: ++dim;
65: }
66: PetscHDF5IntCast(n/bs,count + dim);
67: ++dim;
68: if (bs >= 1) {
69: count[dim] = bs;
70: ++dim;
71: }
72: PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL));
74: /* Select hyperslab in the file */
75: PetscLayoutGetRange(is->map, &low, NULL);
76: dim = 0;
77: if (timestep >= 0) {
78: offset[dim] = timestep;
79: ++dim;
80: }
81: PetscHDF5IntCast(low/bs,offset + dim);
82: ++dim;
83: if (bs >= 1) {
84: offset[dim] = 0;
85: ++dim;
86: }
87: PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL));
89: /* Create property list for collective dataset read */
90: PetscStackCallHDF5Return(plist_id,H5Pcreate,(H5P_DATASET_XFER));
91: #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
92: PetscStackCallHDF5(H5Pset_dxpl_mpio,(plist_id, H5FD_MPIO_COLLECTIVE));
93: #endif
94: /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */
96: #if defined(PETSC_USE_64BIT_INDICES)
97: inttype = H5T_NATIVE_LLONG;
98: #else
99: inttype = H5T_NATIVE_INT;
100: #endif
101: PetscMalloc1(n,&ind);
102: PetscStackCallHDF5(H5Dread,(dset_id, inttype, memspace, filespace, plist_id, (void *) ind));
103: ISGeneralSetIndices(is, n, ind, PETSC_OWN_POINTER);
105: /* Close/release resources */
106: if (group != file_id) PetscStackCallHDF5(H5Gclose,(group));
107: PetscStackCallHDF5(H5Pclose,(plist_id));
108: PetscStackCallHDF5(H5Sclose,(filespace));
109: PetscStackCallHDF5(H5Sclose,(memspace));
110: PetscStackCallHDF5(H5Dclose,(dset_id));
111: return(0);
112: }
113: #endif
117: PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
118: {
119: PetscBool isbinary;
120: #if defined(PETSC_HAVE_HDF5)
121: PetscBool ishdf5;
122: #endif
126: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
127: #if defined(PETSC_HAVE_HDF5)
128: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
129: #endif
130: if (isbinary) {
131: SETERRQ(PetscObjectComm((PetscObject) is), PETSC_ERR_SUP, "This should be implemented");
132: #if defined(PETSC_HAVE_HDF5)
133: } else if (ishdf5) {
134: if (!((PetscObject) is)->name) {
135: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Since HDF5 format gives ASCII name for each object in file; must use ISLoad() after setting name of Vec with PetscObjectSetName()");
136: }
137: ISLoad_HDF5(is, viewer);
138: #endif
139: }
140: return(0);
141: }