Actual source code: hdf5v.c
1: #include <petsc/private/petscimpl.h>
2: #include <petscviewerhdf5.h>
4: /*@C
5: PetscViewerHDF5GetGroup - Get the current HDF5 group name (full path), set with `PetscViewerHDF5PushGroup()`/`PetscViewerHDF5PopGroup()`.
7: Not Collective
9: Input Parameters:
10: + viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
11: - path - (Optional) The path relative to the pushed group
13: Output Parameter:
14: . abspath - The absolute HDF5 path (group)
16: Level: intermediate
18: Notes:
19: If path starts with '/', it is taken as an absolute path overriding currently pushed group, else path is relative to the current pushed group.
20: `NULL` or empty path means the current pushed group.
22: The output abspath is newly allocated so needs to be freed.
24: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5OpenGroup()`, `PetscViewerHDF5WriteGroup()`
25: @*/
26: PetscErrorCode PetscViewerHDF5GetGroup(PetscViewer viewer, const char path[], const char *abspath[])
27: {
28: PetscFunctionBegin;
30: if (path) PetscAssertPointer(path, 2);
31: PetscAssertPointer(abspath, 3);
32: PetscUseMethod(viewer, "PetscViewerHDF5GetGroup_C", (PetscViewer, const char[], const char *[]), (viewer, path, abspath));
33: PetscFunctionReturn(PETSC_SUCCESS);
34: }
36: static PetscErrorCode PetscViewerHDF5CheckNamedObject_Internal(PetscViewer viewer, PetscObject obj)
37: {
38: PetscBool has;
40: PetscFunctionBegin;
41: PetscCall(PetscViewerHDF5HasObject(viewer, obj, &has));
42: if (!has) {
43: const char *group;
44: PetscCall(PetscViewerHDF5GetGroup(viewer, NULL, &group));
45: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Object (dataset) \"%s\" not stored in group %s", obj->name, group);
46: }
47: PetscFunctionReturn(PETSC_SUCCESS);
48: }
50: /*@
51: PetscViewerHDF5SetBaseDimension2 - Vectors of 1 dimension (i.e. bs/dof is 1) will be saved in the HDF5 file with a
52: dimension of 2.
54: Logically Collective
56: Input Parameters:
57: + viewer - the `PetscViewer`; if it is a `PETSCVIEWERHDF5` then this command is ignored
58: - flg - if `PETSC_TRUE` the vector will always have at least a dimension of 2 even if that first dimension is of size 1
60: Options Database Key:
61: . -viewer_hdf5_base_dimension2 - turns on (true) or off (false) using a dimension of 2 in the HDF5 file even if the bs/dof of the vector is 1
63: Level: intermediate
65: Note:
66: Setting this option allegedly makes code that reads the HDF5 in easier since they do not have a "special case" of a bs/dof
67: of one when the dimension is lower. Others think the option is crazy.
69: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerFileSetMode()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerBinaryOpen()`
70: @*/
71: PetscErrorCode PetscViewerHDF5SetBaseDimension2(PetscViewer viewer, PetscBool flg)
72: {
73: PetscFunctionBegin;
75: PetscTryMethod(viewer, "PetscViewerHDF5SetBaseDimension2_C", (PetscViewer, PetscBool), (viewer, flg));
76: PetscFunctionReturn(PETSC_SUCCESS);
77: }
79: /*@
80: PetscViewerHDF5GetBaseDimension2 - Vectors of 1 dimension (i.e. bs/dof is 1) will be saved in the HDF5 file with a
81: dimension of 2.
83: Logically Collective
85: Input Parameter:
86: . viewer - the `PetscViewer`, must be `PETSCVIEWERHDF5`
88: Output Parameter:
89: . flg - if `PETSC_TRUE` the vector will always have at least a dimension of 2 even if that first dimension is of size 1
91: Level: intermediate
93: Note:
94: Setting this option allegedly makes code that reads the HDF5 in easier since they do not have a "special case" of a bs/dof
95: of one when the dimension is lower. Others think the option is crazy.
97: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerFileSetMode()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerBinaryOpen()`
98: @*/
99: PetscErrorCode PetscViewerHDF5GetBaseDimension2(PetscViewer viewer, PetscBool *flg)
100: {
101: PetscFunctionBegin;
103: PetscUseMethod(viewer, "PetscViewerHDF5GetBaseDimension2_C", (PetscViewer, PetscBool *), (viewer, flg));
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }
107: /*@
108: PetscViewerHDF5SetSPOutput - Data is written to disk in single precision even if PETSc is
109: compiled with double precision `PetscReal`.
111: Logically Collective
113: Input Parameters:
114: + viewer - the PetscViewer; if it is a `PETSCVIEWERHDF5` then this command is ignored
115: - flg - if `PETSC_TRUE` the data will be written to disk with single precision
117: Options Database Key:
118: . -viewer_hdf5_sp_output - turns on (true) or off (false) output in single precision
120: Level: intermediate
122: Note:
123: Setting this option does not make any difference if PETSc is compiled with single precision
124: in the first place. It does not affect reading datasets (HDF5 handle this internally).
126: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerFileSetMode()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerBinaryOpen()`,
127: `PetscReal`, `PetscViewerHDF5GetSPOutput()`
128: @*/
129: PetscErrorCode PetscViewerHDF5SetSPOutput(PetscViewer viewer, PetscBool flg)
130: {
131: PetscFunctionBegin;
133: PetscTryMethod(viewer, "PetscViewerHDF5SetSPOutput_C", (PetscViewer, PetscBool), (viewer, flg));
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }
137: /*@
138: PetscViewerHDF5GetSPOutput - Data is written to disk in single precision even if PETSc is
139: compiled with double precision `PetscReal`.
141: Logically Collective
143: Input Parameter:
144: . viewer - the PetscViewer, must be of type `PETSCVIEWERHDF5`
146: Output Parameter:
147: . flg - if `PETSC_TRUE` the data will be written to disk with single precision
149: Level: intermediate
151: .seealso: [](sec_viewers), `PetscViewerFileSetMode()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerBinaryOpen()`,
152: `PetscReal`, `PetscViewerHDF5SetSPOutput()`
153: @*/
154: PetscErrorCode PetscViewerHDF5GetSPOutput(PetscViewer viewer, PetscBool *flg)
155: {
156: PetscFunctionBegin;
158: PetscUseMethod(viewer, "PetscViewerHDF5GetSPOutput_C", (PetscViewer, PetscBool *), (viewer, flg));
159: PetscFunctionReturn(PETSC_SUCCESS);
160: }
162: /*@
163: PetscViewerHDF5SetCollective - Use collective MPI-IO transfer mode for HDF5 reads and writes.
165: Logically Collective; flg must contain common value
167: Input Parameters:
168: + viewer - the `PetscViewer`; if it is not `PETSCVIEWERHDF5` then this command is ignored
169: - flg - `PETSC_TRUE` for collective mode; `PETSC_FALSE` for independent mode (default)
171: Options Database Key:
172: . -viewer_hdf5_collective - turns on (true) or off (false) collective transfers
174: Level: intermediate
176: Note:
177: Collective mode gives the MPI-IO layer underneath HDF5 a chance to do some additional collective optimizations and hence can perform better.
178: However, this works correctly only since HDF5 1.10.3 and if HDF5 is installed for MPI; hence, we ignore this setting for older versions.
180: Developer Notes:
181: In the HDF5 layer, `PETSC_TRUE` / `PETSC_FALSE` means `H5Pset_dxpl_mpio()` is called with `H5FD_MPIO_COLLECTIVE` / `H5FD_MPIO_INDEPENDENT`, respectively.
182: This in turn means use of MPI_File_{read,write}_all / MPI_File_{read,write} in the MPI-IO layer, respectively.
183: See HDF5 documentation and MPI-IO documentation for details.
185: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5GetCollective()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerHDF5Open()`
186: @*/
187: PetscErrorCode PetscViewerHDF5SetCollective(PetscViewer viewer, PetscBool flg)
188: {
189: PetscFunctionBegin;
192: PetscTryMethod(viewer, "PetscViewerHDF5SetCollective_C", (PetscViewer, PetscBool), (viewer, flg));
193: PetscFunctionReturn(PETSC_SUCCESS);
194: }
196: /*@
197: PetscViewerHDF5GetCollective - Return flag whether collective MPI-IO transfer mode is used for HDF5 reads and writes.
199: Not Collective
201: Input Parameter:
202: . viewer - the `PETSCVIEWERHDF5` `PetscViewer`
204: Output Parameter:
205: . flg - the flag
207: Level: intermediate
209: Note:
210: This setting works correctly only since HDF5 1.10.3 and if HDF5 was installed for MPI. For older versions, `PETSC_FALSE` will be always returned.
211: For more details, see `PetscViewerHDF5SetCollective()`.
213: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5SetCollective()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerHDF5Open()`
214: @*/
215: PetscErrorCode PetscViewerHDF5GetCollective(PetscViewer viewer, PetscBool *flg)
216: {
217: PetscFunctionBegin;
219: PetscAssertPointer(flg, 2);
220: PetscUseMethod(viewer, "PetscViewerHDF5GetCollective_C", (PetscViewer, PetscBool *), (viewer, flg));
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: /*@
225: PetscViewerHDF5SetDefaultTimestepping - Set the flag for default timestepping
227: Logically Collective
229: Input Parameters:
230: + viewer - the `PetscViewer`; if it is not `PETSCVIEWERHDF5` then this command is ignored
231: - flg - if `PETSC_TRUE` we will assume that timestepping is on
233: Options Database Key:
234: . -viewer_hdf5_default_timestepping - turns on (true) or off (false) default timestepping
236: Level: intermediate
238: Note:
239: If the timestepping attribute is not found for an object, then the default timestepping is used
241: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5GetDefaultTimestepping()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5GetTimestep()`
242: @*/
243: PetscErrorCode PetscViewerHDF5SetDefaultTimestepping(PetscViewer viewer, PetscBool flg)
244: {
245: PetscFunctionBegin;
247: PetscTryMethod(viewer, "PetscViewerHDF5SetDefaultTimestepping_C", (PetscViewer, PetscBool), (viewer, flg));
248: PetscFunctionReturn(PETSC_SUCCESS);
249: }
251: /*@
252: PetscViewerHDF5GetDefaultTimestepping - Get the flag for default timestepping
254: Not Collective
256: Input Parameter:
257: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
259: Output Parameter:
260: . flg - if `PETSC_TRUE` we will assume that timestepping is on
262: Level: intermediate
264: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5SetDefaultTimestepping()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5GetTimestep()`
265: @*/
266: PetscErrorCode PetscViewerHDF5GetDefaultTimestepping(PetscViewer viewer, PetscBool *flg)
267: {
268: PetscFunctionBegin;
270: PetscUseMethod(viewer, "PetscViewerHDF5GetDefaultTimestepping_C", (PetscViewer, PetscBool *), (viewer, flg));
271: PetscFunctionReturn(PETSC_SUCCESS);
272: }
274: /*@
275: PetscViewerHDF5SetCompress - Set the flag for compression
277: Logically Collective
279: Input Parameters:
280: + viewer - the `PetscViewer`; if it is not `PETSCVIEWERHDF5` then this command is ignored
281: - flg - if `PETSC_TRUE` we will turn on compression
283: Options Database Key:
284: . -viewer_hdf5_compress - turns on (true) or off (false) compression
286: Level: intermediate
288: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5GetCompress()`
289: @*/
290: PetscErrorCode PetscViewerHDF5SetCompress(PetscViewer viewer, PetscBool flg)
291: {
292: PetscFunctionBegin;
294: PetscTryMethod(viewer, "PetscViewerHDF5SetCompress_C", (PetscViewer, PetscBool), (viewer, flg));
295: PetscFunctionReturn(PETSC_SUCCESS);
296: }
298: /*@
299: PetscViewerHDF5GetCompress - Get the flag for compression
301: Not Collective
303: Input Parameter:
304: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
306: Output Parameter:
307: . flg - if `PETSC_TRUE` we will turn on compression
309: Level: intermediate
311: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5SetCompress()`
312: @*/
313: PetscErrorCode PetscViewerHDF5GetCompress(PetscViewer viewer, PetscBool *flg)
314: {
315: PetscFunctionBegin;
317: PetscUseMethod(viewer, "PetscViewerHDF5GetCompress_C", (PetscViewer, PetscBool *), (viewer, flg));
318: PetscFunctionReturn(PETSC_SUCCESS);
319: }
321: /*@C
322: PetscViewerHDF5Open - Opens a file for HDF5 input/output as a `PETSCVIEWERHDF5` `PetscViewer`
324: Collective
326: Input Parameters:
327: + comm - MPI communicator
328: . name - name of file
329: - type - type of file
331: Output Parameter:
332: . hdf5v - `PetscViewer` for HDF5 input/output to use with the specified file
334: Options Database Keys:
335: + -viewer_hdf5_base_dimension2 - turns on (true) or off (false) using a dimension of 2 in the HDF5 file even if the bs/dof of the vector is 1
336: - -viewer_hdf5_sp_output - forces (if true) the viewer to write data in single precision independent on the precision of PetscReal
338: Level: beginner
340: Notes:
341: Reading is always available, regardless of the mode. Available modes are
342: .vb
343: FILE_MODE_READ - open existing HDF5 file for read only access, fail if file does not exist [H5Fopen() with H5F_ACC_RDONLY]
344: FILE_MODE_WRITE - if file exists, fully overwrite it, else create new HDF5 file [H5FcreateH5Fcreate() with H5F_ACC_TRUNC]
345: FILE_MODE_APPEND - if file exists, keep existing contents [H5Fopen() with H5F_ACC_RDWR], else create new HDF5 file [H5FcreateH5Fcreate() with H5F_ACC_EXCL]
346: FILE_MODE_UPDATE - same as FILE_MODE_APPEND
347: .ve
349: In case of `FILE_MODE_APPEND` / `FILE_MODE_UPDATE`, any stored object (dataset, attribute) can be selectively overwritten if the same fully qualified name (/group/path/to/object) is specified.
351: This PetscViewer should be destroyed with PetscViewerDestroy().
353: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerHDF5SetBaseDimension2()`,
354: `PetscViewerHDF5SetSPOutput()`, `PetscViewerHDF5GetBaseDimension2()`, `VecView()`, `MatView()`, `VecLoad()`,
355: `MatLoad()`, `PetscFileMode`, `PetscViewer`, `PetscViewerSetType()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
356: @*/
357: PetscErrorCode PetscViewerHDF5Open(MPI_Comm comm, const char name[], PetscFileMode type, PetscViewer *hdf5v)
358: {
359: PetscFunctionBegin;
360: PetscCall(PetscViewerCreate(comm, hdf5v));
361: PetscCall(PetscViewerSetType(*hdf5v, PETSCVIEWERHDF5));
362: PetscCall(PetscViewerFileSetMode(*hdf5v, type));
363: PetscCall(PetscViewerFileSetName(*hdf5v, name));
364: PetscCall(PetscViewerSetFromOptions(*hdf5v));
365: PetscFunctionReturn(PETSC_SUCCESS);
366: }
368: /*@C
369: PetscViewerHDF5PushGroup - Set the current HDF5 group for output
371: Not Collective
373: Input Parameters:
374: + viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
375: - name - The group name
377: Level: intermediate
379: Notes:
380: This is designed to mnemonically resemble the Unix cd command.
381: .vb
382: If name begins with '/', it is interpreted as an absolute path fully replacing current group, otherwise it is taken as relative to the current group.
383: `NULL`, empty string, or any sequence of all slashes (e.g. "///") is interpreted as the root group "/".
384: "." means the current group is pushed again.
385: .ve
387: Example:
388: Suppose the current group is "/a".
389: .vb
390: If name is `NULL`, empty string, or a sequence of all slashes (e.g. "///"), then the new group will be "/".
391: If name is ".", then the new group will be "/a".
392: If name is "b", then the new group will be "/a/b".
393: If name is "/b", then the new group will be "/b".
394: .ve
396: Developer Notes:
397: The root group "/" is internally stored as `NULL`.
399: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`, `PetscViewerHDF5OpenGroup()`, `PetscViewerHDF5WriteGroup()`
400: @*/
401: PetscErrorCode PetscViewerHDF5PushGroup(PetscViewer viewer, const char name[])
402: {
403: PetscFunctionBegin;
405: if (name) PetscAssertPointer(name, 2);
406: PetscUseMethod(viewer, "PetscViewerHDF5PushGroup_C", (PetscViewer, const char[]), (viewer, name));
407: PetscFunctionReturn(PETSC_SUCCESS);
408: }
410: /*@
411: PetscViewerHDF5PopGroup - Return the current HDF5 group for output to the previous value
413: Not Collective
415: Input Parameter:
416: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
418: Level: intermediate
420: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5GetGroup()`, `PetscViewerHDF5OpenGroup()`, `PetscViewerHDF5WriteGroup()`
421: @*/
422: PetscErrorCode PetscViewerHDF5PopGroup(PetscViewer viewer)
423: {
424: PetscFunctionBegin;
426: PetscUseMethod(viewer, "PetscViewerHDF5PopGroup_C", (PetscViewer), (viewer));
427: PetscFunctionReturn(PETSC_SUCCESS);
428: }
430: /*@C
431: PetscViewerHDF5WriteGroup - Ensure the HDF5 group exists in the HDF5 file
433: Not Collective
435: Input Parameters:
436: + viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
437: - path - (Optional) The path relative to the pushed group
439: Level: intermediate
441: Note:
442: If path starts with '/', it is taken as an absolute path overriding currently pushed group, else path is relative to the current pushed group.
443: `NULL` or empty path means the current pushed group.
445: This will fail if the viewer is not writable.
447: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`, `PetscViewerHDF5OpenGroup()`
448: @*/
449: PetscErrorCode PetscViewerHDF5WriteGroup(PetscViewer viewer, const char path[])
450: {
451: PetscFunctionBegin;
453: PetscUseMethod(viewer, "PetscViewerHDF5WriteGroup_C", (PetscViewer, const char[]), (viewer, path));
454: PetscFunctionReturn(PETSC_SUCCESS);
455: }
457: /*@
458: PetscViewerHDF5PushTimestepping - Activate timestepping mode for subsequent HDF5 reading and writing.
460: Not Collective
462: Input Parameter:
463: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
465: Level: intermediate
467: Notes:
468: On first `PetscViewerHDF5PushTimestepping()`, the initial time step is set to 0.
469: Next timesteps can then be set using `PetscViewerHDF5IncrementTimestep()` or `PetscViewerHDF5SetTimestep()`.
470: Current timestep value determines which timestep is read from or written to any dataset on the next HDF5 I/O operation [e.g. `VecView()`].
471: Use `PetscViewerHDF5PopTimestepping()` to deactivate timestepping mode; calling it by the end of the program is NOT mandatory.
472: Current timestep is remembered between `PetscViewerHDF5PopTimestepping()` and the next `PetscViewerHDF5PushTimestepping()`.
474: If a dataset was stored with timestepping, it can be loaded only in the timestepping mode again.
475: Loading a timestepped dataset with timestepping disabled, or vice-versa results in an error.
477: Developer Notes:
478: Timestepped HDF5 dataset has an extra dimension and attribute "timestepping" set to true.
480: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PopTimestepping()`, `PetscViewerHDF5IsTimestepping()`, `PetscViewerHDF5SetTimestep()`, `PetscViewerHDF5IncrementTimestep()`, `PetscViewerHDF5GetTimestep()`
481: @*/
482: PetscErrorCode PetscViewerHDF5PushTimestepping(PetscViewer viewer)
483: {
484: PetscFunctionBegin;
486: PetscUseMethod(viewer, "PetscViewerHDF5PushTimestepping_C", (PetscViewer), (viewer));
487: PetscFunctionReturn(PETSC_SUCCESS);
488: }
490: /*@
491: PetscViewerHDF5PopTimestepping - Deactivate timestepping mode for subsequent HDF5 reading and writing.
493: Not Collective
495: Input Parameter:
496: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
498: Level: intermediate
500: Note:
501: See `PetscViewerHDF5PushTimestepping()` for details.
503: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5IsTimestepping()`, `PetscViewerHDF5SetTimestep()`, `PetscViewerHDF5IncrementTimestep()`, `PetscViewerHDF5GetTimestep()`
504: @*/
505: PetscErrorCode PetscViewerHDF5PopTimestepping(PetscViewer viewer)
506: {
507: PetscFunctionBegin;
509: PetscUseMethod(viewer, "PetscViewerHDF5PopTimestepping_C", (PetscViewer), (viewer));
510: PetscFunctionReturn(PETSC_SUCCESS);
511: }
513: /*@
514: PetscViewerHDF5IsTimestepping - Ask the viewer whether it is in timestepping mode currently.
516: Not Collective
518: Input Parameter:
519: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
521: Output Parameter:
522: . flg - is timestepping active?
524: Level: intermediate
526: Note:
527: See `PetscViewerHDF5PushTimestepping()` for details.
529: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5PopTimestepping()`, `PetscViewerHDF5SetTimestep()`, `PetscViewerHDF5IncrementTimestep()`, `PetscViewerHDF5GetTimestep()`
530: @*/
531: PetscErrorCode PetscViewerHDF5IsTimestepping(PetscViewer viewer, PetscBool *flg)
532: {
533: PetscFunctionBegin;
535: PetscUseMethod(viewer, "PetscViewerHDF5IsTimestepping_C", (PetscViewer, PetscBool *), (viewer, flg));
536: PetscFunctionReturn(PETSC_SUCCESS);
537: }
539: /*@
540: PetscViewerHDF5IncrementTimestep - Increments current timestep for the HDF5 output. Fields are stacked in time.
542: Not Collective
544: Input Parameter:
545: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
547: Level: intermediate
549: Note:
550: This can be called only if the viewer is in timestepping mode. See `PetscViewerHDF5PushTimestepping()` for details.
552: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5SetTimestep()`, `PetscViewerHDF5GetTimestep()`
553: @*/
554: PetscErrorCode PetscViewerHDF5IncrementTimestep(PetscViewer viewer)
555: {
556: PetscFunctionBegin;
558: PetscUseMethod(viewer, "PetscViewerHDF5IncrementTimestep_C", (PetscViewer), (viewer));
559: PetscFunctionReturn(PETSC_SUCCESS);
560: }
562: /*@
563: PetscViewerHDF5SetTimestep - Set the current timestep for the HDF5 output. Fields are stacked in time.
565: Logically Collective
567: Input Parameters:
568: + viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
569: - timestep - The timestep
571: Level: intermediate
573: Note:
574: This can be called only if the viewer is in timestepping mode. See `PetscViewerHDF5PushTimestepping()` for details.
576: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5IncrementTimestep()`, `PetscViewerHDF5GetTimestep()`
577: @*/
578: PetscErrorCode PetscViewerHDF5SetTimestep(PetscViewer viewer, PetscInt timestep)
579: {
580: PetscFunctionBegin;
583: PetscUseMethod(viewer, "PetscViewerHDF5SetTimestep_C", (PetscViewer, PetscInt), (viewer, timestep));
584: PetscFunctionReturn(PETSC_SUCCESS);
585: }
587: /*@
588: PetscViewerHDF5GetTimestep - Get the current timestep for the HDF5 output. Fields are stacked in time.
590: Not Collective
592: Input Parameter:
593: . viewer - the `PetscViewer` of type `PETSCVIEWERHDF5`
595: Output Parameter:
596: . timestep - The timestep
598: Level: intermediate
600: Note:
601: This can be called only if the viewer is in the timestepping mode. See `PetscViewerHDF5PushTimestepping()` for details.
603: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5PushTimestepping()`, `PetscViewerHDF5IncrementTimestep()`, `PetscViewerHDF5SetTimestep()`
604: @*/
605: PetscErrorCode PetscViewerHDF5GetTimestep(PetscViewer viewer, PetscInt *timestep)
606: {
607: PetscFunctionBegin;
609: PetscAssertPointer(timestep, 2);
610: PetscUseMethod(viewer, "PetscViewerHDF5GetTimestep_C", (PetscViewer, PetscInt *), (viewer, timestep));
611: PetscFunctionReturn(PETSC_SUCCESS);
612: }
614: /*@C
615: PetscViewerHDF5WriteAttribute - Write an attribute
617: Collective
619: Input Parameters:
620: + viewer - The `PETSCVIEWERHDF5` viewer
621: . parent - The parent dataset/group name
622: . name - The attribute name
623: . datatype - The attribute type
624: - value - The attribute value
626: Level: advanced
628: Note:
629: If parent starts with '/', it is taken as an absolute path overriding currently pushed group, else parent is relative to the current pushed group.
630: `NULL` means the current pushed group.
632: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5WriteObjectAttribute()`, `PetscViewerHDF5ReadAttribute()`, `PetscViewerHDF5HasAttribute()`,
633: `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
634: @*/
635: PetscErrorCode PetscViewerHDF5WriteAttribute(PetscViewer viewer, const char parent[], const char name[], PetscDataType datatype, const void *value)
636: {
637: PetscFunctionBegin;
639: if (parent) PetscAssertPointer(parent, 2);
640: PetscAssertPointer(name, 3);
642: PetscAssertPointer(value, 5);
643: PetscUseMethod(viewer, "PetscViewerHDF5WriteAttribute_C", (PetscViewer, const char[], const char[], PetscDataType, const void *), (viewer, parent, name, datatype, value));
644: PetscFunctionReturn(PETSC_SUCCESS);
645: }
647: /*@C
648: PetscViewerHDF5WriteObjectAttribute - Write an attribute to the dataset matching the given `PetscObject` by name
650: Collective
652: Input Parameters:
653: + viewer - The `PETSCVIEWERHDF5` viewer
654: . obj - The object whose name is used to lookup the parent dataset, relative to the current group.
655: . name - The attribute name
656: . datatype - The attribute type
657: - value - The attribute value
659: Level: advanced
661: Note:
662: This fails if the path current_group/object_name doesn't resolve to a dataset (the path doesn't exist or is not a dataset).
663: You might want to check first if it does using `PetscViewerHDF5HasObject()`.
665: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5WriteAttribute()`, `PetscViewerHDF5ReadObjectAttribute()`, `PetscViewerHDF5HasObjectAttribute()`,
666: `PetscViewerHDF5HasObject()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
667: @*/
668: PetscErrorCode PetscViewerHDF5WriteObjectAttribute(PetscViewer viewer, PetscObject obj, const char name[], PetscDataType datatype, const void *value)
669: {
670: PetscFunctionBegin;
673: PetscAssertPointer(name, 3);
675: PetscAssertPointer(value, 5);
676: PetscCall(PetscViewerHDF5CheckNamedObject_Internal(viewer, obj));
677: PetscCall(PetscViewerHDF5WriteAttribute(viewer, obj->name, name, datatype, value));
678: PetscFunctionReturn(PETSC_SUCCESS);
679: }
681: /*@C
682: PetscViewerHDF5ReadAttribute - Read an attribute
684: Collective
686: Input Parameters:
687: + viewer - The `PETSCVIEWERHDF5` viewer
688: . parent - The parent dataset/group name
689: . name - The attribute name
690: . datatype - The attribute type
691: - defaultValue - The pointer to the default value
693: Output Parameter:
694: . value - The pointer to the read HDF5 attribute value
696: Level: advanced
698: Notes:
699: If defaultValue is `NULL` and the attribute is not found, an error occurs.
701: If defaultValue is not `NULL` and the attribute is not found, `defaultValue` is copied to value.
703: The pointers `defaultValue` and `value` can be the same; for instance
704: .vb
705: flg = PETSC_FALSE;
706: PetscCall(`PetscViewerHDF5ReadAttribute`(viewer,name,"attr",PETSC_BOOL,&flg,&flg));
707: .ve
708: is valid, but make sure the default value is initialized.
710: If the datatype is `PETSC_STRING`, the output string is newly allocated so one must `PetscFree()` it when no longer needed.
712: If parent starts with '/', it is taken as an absolute path overriding currently pushed group, else parent is relative to the current pushed group. `NULL` means the current pushed group.
714: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5ReadObjectAttribute()`, `PetscViewerHDF5WriteAttribute()`, `PetscViewerHDF5HasAttribute()`, `PetscViewerHDF5HasObject()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
715: @*/
716: PetscErrorCode PetscViewerHDF5ReadAttribute(PetscViewer viewer, const char parent[], const char name[], PetscDataType datatype, const void *defaultValue, void *value)
717: {
718: PetscFunctionBegin;
720: if (parent) PetscAssertPointer(parent, 2);
721: PetscAssertPointer(name, 3);
723: if (defaultValue) PetscAssertPointer(defaultValue, 5);
724: PetscAssertPointer(value, 6);
725: PetscUseMethod(viewer, "PetscViewerHDF5ReadAttribute_C", (PetscViewer, const char[], const char[], PetscDataType, const void *, void *), (viewer, parent, name, datatype, defaultValue, value));
726: PetscFunctionReturn(PETSC_SUCCESS);
727: }
729: /*@C
730: PetscViewerHDF5ReadObjectAttribute - Read an attribute from the dataset matching the given `PetscObject` by name
732: Collective
734: Input Parameters:
735: + viewer - The `PETSCVIEWERHDF5` viewer
736: . obj - The object whose name is used to lookup the parent dataset, relative to the current group.
737: . name - The attribute name
738: . datatype - The attribute type
739: - defaultValue - The default attribute value
741: Output Parameter:
742: . value - The attribute value
744: Level: advanced
746: Note:
747: This fails if current_group/object_name doesn't resolve to a dataset (the path doesn't exist or is not a dataset).
748: You might want to check first if it does using `PetscViewerHDF5HasObject()`.
750: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5ReadAttribute()`, `PetscViewerHDF5WriteObjectAttribute()`, `PetscViewerHDF5HasObjectAttribute()`,
751: `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
752: @*/
753: PetscErrorCode PetscViewerHDF5ReadObjectAttribute(PetscViewer viewer, PetscObject obj, const char name[], PetscDataType datatype, void *defaultValue, void *value)
754: {
755: PetscFunctionBegin;
758: PetscAssertPointer(name, 3);
759: PetscAssertPointer(value, 6);
760: PetscCall(PetscViewerHDF5CheckNamedObject_Internal(viewer, obj));
761: PetscCall(PetscViewerHDF5ReadAttribute(viewer, obj->name, name, datatype, defaultValue, value));
762: PetscFunctionReturn(PETSC_SUCCESS);
763: }
765: /*@C
766: PetscViewerHDF5HasGroup - Check whether the current (pushed) group exists in the HDF5 file
768: Collective
770: Input Parameters:
771: + viewer - The `PETSCVIEWERHDF5` viewer
772: - path - (Optional) The path relative to the pushed group
774: Output Parameter:
775: . has - Flag for group existence
777: Level: advanced
779: Notes:
780: If path starts with '/', it is taken as an absolute path overriding currently pushed group, else path is relative to the current pushed group.
781: `NULL` or empty path means the current pushed group.
783: If path exists but is not a group, `PETSC_FALSE` is returned.
785: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5HasAttribute()`, `PetscViewerHDF5HasDataset()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`, `PetscViewerHDF5OpenGroup()`
786: @*/
787: PetscErrorCode PetscViewerHDF5HasGroup(PetscViewer viewer, const char path[], PetscBool *has)
788: {
789: PetscFunctionBegin;
791: if (path) PetscAssertPointer(path, 2);
792: PetscAssertPointer(has, 3);
793: PetscUseMethod(viewer, "PetscViewerHDF5HasGroup_C", (PetscViewer, const char[], PetscBool *), (viewer, path, has));
794: PetscFunctionReturn(PETSC_SUCCESS);
795: }
797: /*@C
798: PetscViewerHDF5HasDataset - Check whether a given dataset exists in the HDF5 file
800: Collective
802: Input Parameters:
803: + viewer - The `PETSCVIEWERHDF5` viewer
804: - path - The dataset path
806: Output Parameter:
807: . has - Flag whether dataset exists
809: Level: advanced
811: Notes:
812: If path starts with '/', it is taken as an absolute path overriding currently pushed group, else path is relative to the current pushed group.
814: If `path` is `NULL` or empty, has is set to `PETSC_FALSE`.
816: If `path` exists but is not a dataset, has is set to `PETSC_FALSE` as well.
818: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5HasObject()`, `PetscViewerHDF5HasAttribute()`, `PetscViewerHDF5HasGroup()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
819: @*/
820: PetscErrorCode PetscViewerHDF5HasDataset(PetscViewer viewer, const char path[], PetscBool *has)
821: {
822: PetscFunctionBegin;
824: if (path) PetscAssertPointer(path, 2);
825: PetscAssertPointer(has, 3);
826: PetscUseMethod(viewer, "PetscViewerHDF5HasDataset_C", (PetscViewer, const char[], PetscBool *), (viewer, path, has));
827: PetscFunctionReturn(PETSC_SUCCESS);
828: }
830: /*@
831: PetscViewerHDF5HasObject - Check whether a dataset with the same name as given object exists in the HDF5 file under current group
833: Collective
835: Input Parameters:
836: + viewer - The `PETSCVIEWERHDF5` viewer
837: - obj - The named object
839: Output Parameter:
840: . has - Flag for dataset existence
842: Level: advanced
844: Notes:
845: If the object is unnamed, an error occurs.
847: If the path current_group/object_name exists but is not a dataset, has is set to `PETSC_FALSE` as well.
849: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5HasDataset()`, `PetscViewerHDF5HasAttribute()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
850: @*/
851: PetscErrorCode PetscViewerHDF5HasObject(PetscViewer viewer, PetscObject obj, PetscBool *has)
852: {
853: size_t len;
855: PetscFunctionBegin;
858: PetscAssertPointer(has, 3);
859: PetscCall(PetscStrlen(obj->name, &len));
860: PetscCheck(len, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONG, "Object must be named");
861: PetscCall(PetscViewerHDF5HasDataset(viewer, obj->name, has));
862: PetscFunctionReturn(PETSC_SUCCESS);
863: }
865: /*@C
866: PetscViewerHDF5HasAttribute - Check whether an attribute exists
868: Collective
870: Input Parameters:
871: + viewer - The `PETSCVIEWERHDF5` viewer
872: . parent - The parent dataset/group name
873: - name - The attribute name
875: Output Parameter:
876: . has - Flag for attribute existence
878: Level: advanced
880: Note:
881: If parent starts with '/', it is taken as an absolute path overriding currently pushed group, else parent is relative to the current pushed group. `NULL` means the current pushed group.
883: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5HasObjectAttribute()`, `PetscViewerHDF5WriteAttribute()`, `PetscViewerHDF5ReadAttribute()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
884: @*/
885: PetscErrorCode PetscViewerHDF5HasAttribute(PetscViewer viewer, const char parent[], const char name[], PetscBool *has)
886: {
887: PetscFunctionBegin;
889: if (parent) PetscAssertPointer(parent, 2);
890: PetscAssertPointer(name, 3);
891: PetscAssertPointer(has, 4);
892: PetscUseMethod(viewer, "PetscViewerHDF5HasAttribute_C", (PetscViewer, const char[], const char[], PetscBool *), (viewer, parent, name, has));
893: PetscFunctionReturn(PETSC_SUCCESS);
894: }
896: /*@C
897: PetscViewerHDF5HasObjectAttribute - Check whether an attribute is attached to the dataset matching the given `PetscObject` by name
899: Collective
901: Input Parameters:
902: + viewer - The `PETSCVIEWERHDF5` viewer
903: . obj - The object whose name is used to lookup the parent dataset, relative to the current group.
904: - name - The attribute name
906: Output Parameter:
907: . has - Flag for attribute existence
909: Level: advanced
911: Note:
912: This fails if current_group/object_name doesn't resolve to a dataset (the path doesn't exist or is not a dataset).
913: You might want to check first if it does using `PetscViewerHDF5HasObject()`.
915: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerHDF5HasAttribute()`, `PetscViewerHDF5WriteObjectAttribute()`, `PetscViewerHDF5ReadObjectAttribute()`, `PetscViewerHDF5HasObject()`, `PetscViewerHDF5PushGroup()`, `PetscViewerHDF5PopGroup()`, `PetscViewerHDF5GetGroup()`
916: @*/
917: PetscErrorCode PetscViewerHDF5HasObjectAttribute(PetscViewer viewer, PetscObject obj, const char name[], PetscBool *has)
918: {
919: PetscFunctionBegin;
922: PetscAssertPointer(name, 3);
923: PetscAssertPointer(has, 4);
924: PetscCall(PetscViewerHDF5CheckNamedObject_Internal(viewer, obj));
925: PetscCall(PetscViewerHDF5HasAttribute(viewer, obj->name, name, has));
926: PetscFunctionReturn(PETSC_SUCCESS);
927: }
929: /*
930: The variable Petsc_Viewer_HDF5_keyval is used to indicate an MPI attribute that
931: is attached to a communicator, in this case the attribute is a PetscViewer.
932: */
933: PetscMPIInt Petsc_Viewer_HDF5_keyval = MPI_KEYVAL_INVALID;
935: /*@C
936: PETSC_VIEWER_HDF5_ - Creates an `PETSCVIEWERHDF5` `PetscViewer` shared by all processors in a communicator.
938: Collective
940: Input Parameter:
941: . comm - the MPI communicator to share the `PETSCVIEWERHDF5` `PetscViewer`
943: Options Database Key:
944: . -viewer_hdf5_filename name - name of the HDF5 file
946: Environmental variable:
947: . `PETSC_VIEWER_HDF5_FILENAME` - name of the HDF5 file
949: Level: intermediate
951: Note:
952: Unlike almost all other PETSc routines, `PETSC_VIEWER_HDF5_()` does not return
953: an error code. The HDF5 `PetscViewer` is usually used in the form
954: .vb
955: XXXView(XXX object, PETSC_VIEWER_HDF5_(comm));
956: .ve
958: .seealso: [](sec_viewers), `PETSCVIEWERHDF5`, `PetscViewerHDF5Open()`, `PetscViewerCreate()`, `PetscViewerDestroy()`
959: @*/
960: PetscViewer PETSC_VIEWER_HDF5_(MPI_Comm comm)
961: {
962: PetscErrorCode ierr;
963: PetscMPIInt mpi_ierr;
964: PetscBool flg;
965: PetscMPIInt iflg;
966: PetscViewer viewer;
967: char fname[PETSC_MAX_PATH_LEN];
968: MPI_Comm ncomm;
970: PetscFunctionBegin;
971: ierr = PetscCommDuplicate(comm, &ncomm, NULL);
972: if (ierr) {
973: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
974: PetscFunctionReturn(NULL);
975: }
976: if (Petsc_Viewer_HDF5_keyval == MPI_KEYVAL_INVALID) {
977: mpi_ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_HDF5_keyval, NULL);
978: if (mpi_ierr) {
979: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
980: PetscFunctionReturn(NULL);
981: }
982: }
983: mpi_ierr = MPI_Comm_get_attr(ncomm, Petsc_Viewer_HDF5_keyval, (void **)&viewer, &iflg);
984: if (mpi_ierr) {
985: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
986: PetscFunctionReturn(NULL);
987: }
988: if (!iflg) { /* PetscViewer not yet created */
989: ierr = PetscOptionsGetenv(ncomm, "PETSC_VIEWER_HDF5_FILENAME", fname, PETSC_MAX_PATH_LEN, &flg);
990: if (ierr) {
991: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
992: PetscFunctionReturn(NULL);
993: }
994: if (!flg) {
995: ierr = PetscStrncpy(fname, "output.h5", sizeof(fname));
996: if (ierr) {
997: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
998: PetscFunctionReturn(NULL);
999: }
1000: }
1001: ierr = PetscViewerHDF5Open(ncomm, fname, FILE_MODE_WRITE, &viewer);
1002: if (ierr) {
1003: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
1004: PetscFunctionReturn(NULL);
1005: }
1006: ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
1007: if (ierr) {
1008: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
1009: PetscFunctionReturn(NULL);
1010: }
1011: mpi_ierr = MPI_Comm_set_attr(ncomm, Petsc_Viewer_HDF5_keyval, (void *)viewer);
1012: if (mpi_ierr) {
1013: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
1014: PetscFunctionReturn(NULL);
1015: }
1016: }
1017: ierr = PetscCommDestroy(&ncomm);
1018: if (ierr) {
1019: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_HDF5_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
1020: PetscFunctionReturn(NULL);
1021: }
1022: PetscFunctionReturn(viewer);
1023: }