From 63fc02bae8bfc38433cdd45011258901c25c7269 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Tue, 17 May 2022 14:55:03 -0500 Subject: Add H5S UG chapter, adjust details (#1775) --- doxygen/CMakeLists.txt | 2 +- doxygen/img/Dspace_CvsF1.gif | Bin 0 -> 8623 bytes doxygen/img/Dspace_CvsF2.gif | Bin 0 -> 8623 bytes doxygen/img/Dspace_CvsF3.gif | Bin 0 -> 8909 bytes doxygen/img/Dspace_CvsF4.gif | Bin 0 -> 8470 bytes doxygen/img/Dspace_combine.gif | Bin 0 -> 5101 bytes doxygen/img/Dspace_complex.gif | Bin 0 -> 6715 bytes doxygen/img/Dspace_features.gif | Bin 0 -> 89809 bytes doxygen/img/Dspace_features_cmpd.gif | Bin 0 -> 31274 bytes doxygen/img/Dspace_move.gif | Bin 0 -> 13255 bytes doxygen/img/Dspace_point.gif | Bin 0 -> 6697 bytes doxygen/img/Dspace_read.gif | Bin 0 -> 14238 bytes doxygen/img/Dspace_select.gif | Bin 0 -> 29452 bytes doxygen/img/Dspace_separate.gif | Bin 0 -> 9911 bytes doxygen/img/Dspace_simple.gif | Bin 0 -> 9709 bytes doxygen/img/Dspace_subset.gif | Bin 0 -> 4790 bytes doxygen/img/Dspace_three_datasets.gif | Bin 0 -> 10912 bytes doxygen/img/Dspace_transfer.gif | Bin 0 -> 15096 bytes doxygen/img/Dspace_write1to2.gif | Bin 0 -> 38748 bytes src/H5Amodule.h | 16 +- src/H5Emodule.h | 4 +- src/H5Epublic.h | 8 +- src/H5FDfamily.h | 4 +- src/H5FDmpio.h | 6 +- src/H5FDmulti.h | 4 +- src/H5FDsec2.h | 2 +- src/H5FDstdio.h | 2 +- src/H5Pmodule.h | 17 +- src/H5Rpublic.h | 20 +- src/H5Smodule.h | 1469 ++++++++++++++++++++++++++++++++- 30 files changed, 1524 insertions(+), 30 deletions(-) create mode 100644 doxygen/img/Dspace_CvsF1.gif create mode 100644 doxygen/img/Dspace_CvsF2.gif create mode 100644 doxygen/img/Dspace_CvsF3.gif create mode 100644 doxygen/img/Dspace_CvsF4.gif create mode 100644 doxygen/img/Dspace_combine.gif create mode 100644 doxygen/img/Dspace_complex.gif create mode 100644 doxygen/img/Dspace_features.gif create mode 100644 doxygen/img/Dspace_features_cmpd.gif create mode 100644 doxygen/img/Dspace_move.gif create mode 100644 doxygen/img/Dspace_point.gif create mode 100644 doxygen/img/Dspace_read.gif create mode 100644 doxygen/img/Dspace_select.gif create mode 100644 doxygen/img/Dspace_separate.gif create mode 100644 doxygen/img/Dspace_simple.gif create mode 100644 doxygen/img/Dspace_subset.gif create mode 100644 doxygen/img/Dspace_three_datasets.gif create mode 100644 doxygen/img/Dspace_transfer.gif create mode 100644 doxygen/img/Dspace_write1to2.gif diff --git a/doxygen/CMakeLists.txt b/doxygen/CMakeLists.txt index 38c2fad..e75c899 100644 --- a/doxygen/CMakeLists.txt +++ b/doxygen/CMakeLists.txt @@ -21,7 +21,7 @@ if (DOXYGEN_FOUND) set (DOXYGEN_HTML_HEADER ${HDF5_DOXYGEN_DIR}/hdf5_header.html) set (DOXYGEN_HTML_FOOTER ${HDF5_DOXYGEN_DIR}/hdf5_footer.html) set (DOXYGEN_HTML_EXTRA_STYLESHEET ${HDF5_DOXYGEN_DIR}/hdf5doxy.css) - set (DOXYGEN_HTML_EXTRA_FILES "${HDF5_DOXYGEN_DIR}/hdf5_navtree_hacks.js ${HDF5_DOXYGEN_DIR}/img/FF-IH_FileGroup.gif ${HDF5_DOXYGEN_DIR}/img/FF-IH_FileObject.gif ${HDF5_DOXYGEN_DIR}/img/FileFormatSpecChunkDiagram.jpg ${HDF5_DOXYGEN_DIR}/img/ftv2node.png ${HDF5_DOXYGEN_DIR}/img/ftv2pnode.png ${HDF5_DOXYGEN_DIR}/img/HDFG-logo.png ${HDF5_DOXYGEN_DIR}/img/IOFlow2.gif ${HDF5_DOXYGEN_DIR}/img/IOFlow3.gif ${HDF5_DOXYGEN_DIR}/img/IOFlow.gif ${HDF5_DOXYGEN_DIR}/img/PaletteExample1.gif ${HDF5_DOXYGEN_DIR}/img/Palettes.fm.anc.gif ${HDF5_DOXYGEN_DIR}/img/UML_Attribute.jpg ${HDF5_DOXYGEN_DIR}/img/Shared_Attribute.jpg") + set (DOXYGEN_HTML_EXTRA_FILES "${HDF5_DOXYGEN_DIR}/hdf5_navtree_hacks.js") set (DOXYGEN_TAG_FILE ${HDF5_BINARY_DIR}/hdf5.tag) set (DOXYGEN_SERVER_BASED_SEARCH NO) set (DOXYGEN_EXTERNAL_SEARCH NO) diff --git a/doxygen/img/Dspace_CvsF1.gif b/doxygen/img/Dspace_CvsF1.gif new file mode 100644 index 0000000..716b9f1 Binary files /dev/null and b/doxygen/img/Dspace_CvsF1.gif differ diff --git a/doxygen/img/Dspace_CvsF2.gif b/doxygen/img/Dspace_CvsF2.gif new file mode 100644 index 0000000..716b9f1 Binary files /dev/null and b/doxygen/img/Dspace_CvsF2.gif differ diff --git a/doxygen/img/Dspace_CvsF3.gif b/doxygen/img/Dspace_CvsF3.gif new file mode 100644 index 0000000..59c31ff Binary files /dev/null and b/doxygen/img/Dspace_CvsF3.gif differ diff --git a/doxygen/img/Dspace_CvsF4.gif b/doxygen/img/Dspace_CvsF4.gif new file mode 100644 index 0000000..e97b006 Binary files /dev/null and b/doxygen/img/Dspace_CvsF4.gif differ diff --git a/doxygen/img/Dspace_combine.gif b/doxygen/img/Dspace_combine.gif new file mode 100644 index 0000000..8da2397 Binary files /dev/null and b/doxygen/img/Dspace_combine.gif differ diff --git a/doxygen/img/Dspace_complex.gif b/doxygen/img/Dspace_complex.gif new file mode 100644 index 0000000..53e92ee Binary files /dev/null and b/doxygen/img/Dspace_complex.gif differ diff --git a/doxygen/img/Dspace_features.gif b/doxygen/img/Dspace_features.gif new file mode 100644 index 0000000..d94b4e4 Binary files /dev/null and b/doxygen/img/Dspace_features.gif differ diff --git a/doxygen/img/Dspace_features_cmpd.gif b/doxygen/img/Dspace_features_cmpd.gif new file mode 100644 index 0000000..f24ee99 Binary files /dev/null and b/doxygen/img/Dspace_features_cmpd.gif differ diff --git a/doxygen/img/Dspace_move.gif b/doxygen/img/Dspace_move.gif new file mode 100644 index 0000000..5debd75 Binary files /dev/null and b/doxygen/img/Dspace_move.gif differ diff --git a/doxygen/img/Dspace_point.gif b/doxygen/img/Dspace_point.gif new file mode 100644 index 0000000..92ad3a8 Binary files /dev/null and b/doxygen/img/Dspace_point.gif differ diff --git a/doxygen/img/Dspace_read.gif b/doxygen/img/Dspace_read.gif new file mode 100644 index 0000000..28c67f4 Binary files /dev/null and b/doxygen/img/Dspace_read.gif differ diff --git a/doxygen/img/Dspace_select.gif b/doxygen/img/Dspace_select.gif new file mode 100644 index 0000000..b9f4851 Binary files /dev/null and b/doxygen/img/Dspace_select.gif differ diff --git a/doxygen/img/Dspace_separate.gif b/doxygen/img/Dspace_separate.gif new file mode 100644 index 0000000..ba4ba8c Binary files /dev/null and b/doxygen/img/Dspace_separate.gif differ diff --git a/doxygen/img/Dspace_simple.gif b/doxygen/img/Dspace_simple.gif new file mode 100644 index 0000000..ff3eca5 Binary files /dev/null and b/doxygen/img/Dspace_simple.gif differ diff --git a/doxygen/img/Dspace_subset.gif b/doxygen/img/Dspace_subset.gif new file mode 100644 index 0000000..b353175 Binary files /dev/null and b/doxygen/img/Dspace_subset.gif differ diff --git a/doxygen/img/Dspace_three_datasets.gif b/doxygen/img/Dspace_three_datasets.gif new file mode 100644 index 0000000..4af222f Binary files /dev/null and b/doxygen/img/Dspace_three_datasets.gif differ diff --git a/doxygen/img/Dspace_transfer.gif b/doxygen/img/Dspace_transfer.gif new file mode 100644 index 0000000..7de0231 Binary files /dev/null and b/doxygen/img/Dspace_transfer.gif differ diff --git a/doxygen/img/Dspace_write1to2.gif b/doxygen/img/Dspace_write1to2.gif new file mode 100644 index 0000000..5735bc7 Binary files /dev/null and b/doxygen/img/Dspace_write1to2.gif differ diff --git a/src/H5Amodule.h b/src/H5Amodule.h index 62851ff..ba5a9df 100644 --- a/src/H5Amodule.h +++ b/src/H5Amodule.h @@ -63,12 +63,18 @@ * attached directly to that object * * \subsection subsec_error_H5A Attribute Function Summaries - * \ref H5A reference manual + * @see H5A reference manual * * \subsection subsec_attribute_program Programming Model for Attributes * * The figure below shows the UML model for an HDF5 attribute and its associated dataspace and datatype. + * + * + * + * + *
* \image html UML_Attribute.jpg "The UML model for an HDF5 attribute" + *
* * Creating an attribute is similar to creating a dataset. To create an attribute, the application must * specify the object to which the attribute is attached, the datatype and dataspace of the attribute @@ -329,7 +335,13 @@ * This way of handling large attributes can be used in situations where backward compatibility is important * and where compression is important. Applications built with versions before 1.8.x can read large * attributes stored in separate datasets. Datasets can be compressed while attributes cannot. + * + * + * + * + *
* \image html Shared_Attribute.jpg "A large or shared HDF5 attribute and its associated dataset(s)" + *
* Note: In the figure above, DatasetA is an attribute of Dataset1 that is too large to store in Dataset1's * header. DatasetA is associated with Dataset1 by means of an object reference pointer attached as an * attribute to Dataset1. The attribute in DatasetA can be shared among multiple datasets by means of @@ -368,7 +380,7 @@ * An HDF5 attribute is a small metadata object describing the nature and/or intended usage of a primary data * object. A primary data object may be a dataset, group, or committed datatype. * - * See \ref sec_attribute + * @see sec_attribute * */ diff --git a/src/H5Emodule.h b/src/H5Emodule.h index f3edebd..3a65bed 100644 --- a/src/H5Emodule.h +++ b/src/H5Emodule.h @@ -62,7 +62,7 @@ * design for the Error Handling API. * * \subsection subsec_error_H5E Error Handling Function Summaries - * \ref H5E reference manual + * @see H5E reference manual * * \subsection subsec_error_program Programming Model for Error Handling * This section is under construction. @@ -605,7 +605,7 @@ * error stack. The error stack is statically allocated to reduce the * complexity of handling errors within the \ref H5E package. * - * See \ref sec_error + * @see sec_error * */ diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 43eb4fc..e092ab0 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -879,8 +879,8 @@ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client * * \deprecated 1.8.0 Function deprecated in this release. * - * \details Given a major error number, H5Eget_major() returns a constant - * character string that describes the error. + * \details H5Eget_major() returns a constant + * character string that describes the error, given a major error number. * * \attention This function returns a dynamically allocated string (\c char * array). An application calling this function must free the memory @@ -900,8 +900,8 @@ H5_DLL char *H5Eget_major(H5E_major_t maj); * * \deprecated 1.8.0 Function deprecated and return type changed in this release. * - * \details Given a minor error number, H5Eget_minor() returns a constant - * character string that describes the error. + * \details H5Eget_minor() returns a constant + * character string that describes the error, given a minor error number. * * \attention In the Release 1.8.x series, H5Eget_minor() returns a string of * dynamic allocated \c char array. An application calling this diff --git a/src/H5FDfamily.h b/src/H5FDfamily.h index d07d659..20ef532 100644 --- a/src/H5FDfamily.h +++ b/src/H5FDfamily.h @@ -39,7 +39,7 @@ H5_DLL hid_t H5FD_family_init(void); * each family member * \returns \herr_t * - * \details H5Pset_fapl_family sets the file access property list identifier, + * \details H5Pset_fapl_family() sets the file access property list identifier, * \p fapl_id, to use the family driver. * * \p memb_size is the size in bytes of each file member. This size @@ -71,7 +71,7 @@ H5_DLL herr_t H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fa * each family member * \returns \herr_t * - * \details H5Pget_fapl_family returns file access property list for use with + * \details H5Pget_fapl_family() returns file access property list for use with * the family driver. This information is returned through the output * parameters. * diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h index a70f34b..ba508eb 100644 --- a/src/H5FDmpio.h +++ b/src/H5FDmpio.h @@ -104,10 +104,10 @@ H5_DLL herr_t H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info); * \param[out] info MPI-2 info object * \returns \herr_t * - * \details If the file access property list is set to the #H5FD_MPIO driver, - * H5Pget_fapl_mpio() returns duplicates of the stored MPI communicator + * \details H5Pget_fapl_mpio() returns duplicates of the stored MPI communicator * and Info object through the \p comm and \p info pointers, if those - * values are non-null. + * values are non-null. The file access property list must be set to the + * #H5FD_MPIO driver. * * Since the MPI communicator and Info object are duplicates of the * stored information, future modifications to the access property list diff --git a/src/H5FDmulti.h b/src/H5FDmulti.h index defaa84..62cc9c8 100644 --- a/src/H5FDmulti.h +++ b/src/H5FDmulti.h @@ -172,7 +172,7 @@ H5_DLL herr_t H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const * \param[out] relax Allows read-only access to incomplete file sets when \c TRUE * \returns \herr_t * - * \details H5Pget_fapl_multi returns information about the multi-file access + * \details H5Pget_fapl_multi() returns information about the multi-file access * property list. * * \since 1.4.0 @@ -193,7 +193,7 @@ H5_DLL herr_t H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid * \param[in] raw_plist_id * \returns \herr_t * - * \details H5Pset_fapl_split is a compatibility function that enables the + * \details H5Pset_fapl_split() is a compatibility function that enables the * multi-file driver to emulate the split driver from HDF5 Releases 1.0 * and 1.2. The split file driver stored metadata and raw data in * separate files but provided no mechanism for separating types of diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h index 773f968..d0811ed 100644 --- a/src/H5FDsec2.h +++ b/src/H5FDsec2.h @@ -35,7 +35,7 @@ H5_DLL hid_t H5FD_sec2_init(void); * \fapl_id * \returns \herr_t * - * \details H5Pset_fapl_sec2 modifies the file access property list to use + * \details H5Pset_fapl_sec2() modifies the file access property list to use * the sec2 driver, H5FDsec2. * * \since 1.4.0 diff --git a/src/H5FDstdio.h b/src/H5FDstdio.h index 42cd6a0..6d1cdf3 100644 --- a/src/H5FDstdio.h +++ b/src/H5FDstdio.h @@ -37,7 +37,7 @@ H5_DLL hid_t H5FD_stdio_init(void); * \fapl_id * \returns \herr_t * - * \details H5Pset_fapl_stdio modifies the file access property list to use + * \details H5Pset_fapl_stdio() modifies the file access property list to use * the standard I/O driver, H5FDstdio. * * \since 1.4.0 diff --git a/src/H5Pmodule.h b/src/H5Pmodule.h index 5bd45a2..fc493f9 100644 --- a/src/H5Pmodule.h +++ b/src/H5Pmodule.h @@ -69,7 +69,13 @@ * After reading that material, the reader should have a reasonably complete understanding of how * properties and property lists can be used in HDF5 applications. * + * + * + * + * + *
* \image html PropListEcosystem.gif "The HDF5 property environment" + *
* * The remaining sections in this chapter discuss the following topics: * \li What are properties, property lists, and property list classes? @@ -305,7 +311,13 @@ * creation of any object while the \ref GCPL (GCPL) inherits only those * properties that are relevant to group creation. * + * + * + * + * + *
* \image html PropListClassInheritance.gif "HDF5 property list class inheritance hierarchy" + *
* Note: In the figure above, property list classes displayed in black are directly accessible through * the programming interface; the root of the property environment and the \ref STRCPL and \ref OCPL * property list classes, in gray above, are not user-accessible. The red empty set symbol indicates @@ -313,7 +325,6 @@ * properties. For more information, see \ref FileMountProps "File Mount Properties". Abbreviations * used in this figure are defined in the preceding table, “Property list classes in HDF5”. * - * * \subsubsection subsubsec_plist_lists Property Lists * * A property list is a collection of related properties that are used together in specific @@ -918,13 +929,13 @@ * The second creation property applies to links only, and advises the library * to automatically create missing intermediate groups when creating new objects. * - * See \ref STRCPL + * @see STRCPL * * \defgroup ACPL Attribute Creation Properties * \ingroup STRCPL * The creation property, the choice of a character encoding, applies to attributes. * - * See \ref STRCPL + * @see STRCPL * * \defgroup LAPL Link Access Properties * \ingroup H5P diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index a21f5a0..99a6d44 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -121,6 +121,7 @@ extern "C" { * \since 1.8.0 */ H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); + /** * -------------------------------------------------------------------------- * \ingroup H5R @@ -135,8 +136,8 @@ H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t re * \return Returns identifier of referenced object if successful; otherwise * returns a negative value. * - * \details Given a reference, \p ref, to an object or a region in an object, - * H5Rdereference2() opens that object and returns an identifier. + * \details H5Rdereference2() opens an object or a region in an object and + * returns an identifier to that object, given a reference, \p ref. * * The parameter \p obj_id must be a valid identifier for the HDF5 file * containing the referenced object or for any object in that HDF5 @@ -162,6 +163,7 @@ H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t re * */ H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); + /** * -------------------------------------------------------------------------- * \ingroup H5R @@ -192,6 +194,7 @@ H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, c * */ H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); + /** * -------------------------------------------------------------------------- * \ingroup H5R @@ -206,8 +209,8 @@ H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); * * \return \herr_t * - * \details Given an object reference, \p ref, H5Rget_obj_type2() returns the - * type of the referenced object in \p obj_type. + * \details H5Rget_obj_type2() returns the type of the referenced object in + * \p obj_type, given an object reference, \p ref. * * A \Emph{reference type} is the type of reference, either an object * reference or a dataset region reference. An \Emph{object reference} @@ -248,6 +251,7 @@ H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); * */ H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type); + /** * -------------------------------------------------------------------------- * \ingroup H5R @@ -333,8 +337,8 @@ H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, c * deprecated in favor of the macro H5Rget_obj_type() or the * function H5Rget_obj_type2(). * - * \details Given an object reference, \p ref, H5Rget_obj_type1() returns the - * type of the referenced object. + * \details H5Rget_obj_type1() returns the + * type of the referenced object, given an object reference. * * A \Emph{reference type} is the type of reference, either an object * reference or a dataset region reference. An \Emph{object reference} @@ -395,8 +399,8 @@ H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref * deprecated in favor of the macro H5Rdereference() or the function * H5Rdereference2(). * - * \details Given a reference, \p ref, to an object or a region in an object, - * H5Rdereference1() opens that object and returns an identifier. + * \details H5Rdereference1() opens an object or a region in an object and + * returns an identifier to that object, given a reference, \p ref. * * The parameter \p obj_id must be a valid identifier for an object in * the HDF5 file containing the referenced object, including the file diff --git a/src/H5Smodule.h b/src/H5Smodule.h index fc60ed7..9ccce1b 100644 --- a/src/H5Smodule.h +++ b/src/H5Smodule.h @@ -33,21 +33,1487 @@ * * * \section sec_dataspace HDF5 Dataspaces and Partial I/O + * + * HDF5 dataspaces describe the \Emph{shape} of datasets in memory or in HDF5 + * files. Dataspaces can be empty (#H5S_NULL), a singleton (#H5S_SCALAR), or + * a multi-dimensional, regular grid (#H5S_SIMPLE). Dataspaces can be re-shaped. + * + * Subsets of dataspaces can be "book-marked" or used to restrict I/O operations + * using \Emph{selections}. Furthermore, certain set operations are supported + * for selections. + * * \subsection subsec_dataspace_intro Introduction + * + * The HDF5 \Emph{dataspace} is a required component of an HDF5 dataset or attribute definition. The dataspace + * defines the size and shape of the dataset or attribute raw data. In other words, a dataspace defines the + * number of dimensions and the size of each dimension of the multidimensional array in which the raw data + * is represented. The dataspace must be defined when the dataset or attribute is created. + * + * The \Emph{dataspace} is also used during dataset I/O operations, defining the elements of the dataset that + * participate in the I/O operation. + * + * This chapter explains the \Emph{dataspace} object and its use in dataset and attribute creation and data + * transfer. It also describes selection operations on a dataspace used to implement sub‐setting, + * sub‐sampling, and scatter‐gather access to datasets. + * * \subsection subsec_dataspace_function Dataspace Function Summaries + * The @see H5S reference manual provides a reference list of dataspace functions, the H5S APIs. + * * \subsection subsec_dataspace_program Definition of Dataspace Objects and the Dataspace Programming Model + * + * This section introduces the notion of the HDF5 dataspace object and a programming model for creating + * and working with dataspaces. + * * \subsubsection subsubsec_dataspace_program_object Dataspace Objects + * + * An HDF5 dataspace is a required component of an HDF5 dataset or attribute. A dataspace defines the size + * and the shape of a dataset’s or an attribute’s raw data. Currently, HDF5 supports the following types of + * the dataspaces: + * \li Scalar dataspaces + * \li Simple dataspaces + * \li Null dataspaces + * + * A scalar dataspace, #H5S_SCALAR, represents just one element, a scalar. Note that the datatype of this one + * element may be very complex; example would be a compound structure with members being of any + * allowed HDF5 datatype, including multidimensional arrays, strings, and nested compound structures. By + * convention, the rank of a scalar dataspace is always 0 (zero); think of it geometrically as a single, + * dimensionless point, though that point may be complex. + * + * A simple dataspace, #H5S_SIMPLE , is a multidimensional array of elements. The dimensionality of the + * dataspace (or the rank of the array) is fixed and is defined at creation time. The size of each dimension + * can grow during the life time of the dataspace from the current size up to the maximum size. Both the + * current size and the maximum size are specified at creation time. The sizes of dimensions at any particular + * time in the life of a dataspace are called the current dimensions, or the dataspace extent. They can be + * queried along with the maximum sizes. + * + * A null dataspace, #H5S_NULL, contains no data elements. Note that no selections can be applied to a null + * dataset as there is nothing to select. + * + * As shown in the UML diagram in the figure below, an HDF5 simple dataspace object has three attributes: + * the rank or number of dimensions; the current sizes, expressed as an array of length rank with each element + * of the array denoting the current size of the corresponding dimension; and the maximum sizes, + * expressed as an array of length rank with each element of the array denoting the maximum size of the + * corresponding dimension. + * + * + * + * + * + *
+ * \image html Dspace_simple.gif "A simple dataspace" + *
+ * + * \em Note: A simple dataspace is defined by its rank, the current size of each dimension, and the maximum + * size of each dimension. + * + * The size of a current dimension cannot be greater than the maximum size, which can be unlimited, specified + * as #H5S_UNLIMITED. Note that while the HDF5 file format and library impose no maximum size on an + * unlimited dimension, practically speaking its size will always be limited to the biggest integer available + * on the particular system being used. + * + * Dataspace rank is restricted to 32, the standard limit in C on the rank of an array, in the current + * implementation of the HDF5 Library. The HDF5 file format, on the other hand, allows any rank up to the + * maximum integer value on the system, so the library restriction can be raised in the future if higher + * dimensionality is required. + * + * Note that most of the time Fortran applications calling HDF5 will work with dataspaces of rank less than + * or equal to seven, since seven is the maximum number of dimensions in a Fortran array. But dataspace rank + * is not limited to seven for Fortran applications. + * + * The current dimensions of a dataspace, also referred to as the dataspace extent, define the bounding box + * for dataset elements that can participate in I/O operations. + * * \subsubsection subsubsec_dataspace_program_model Dataspace Programming Model + * + * The programming model for creating and working with HDF5 dataspaces can be summarized as follows: + * \li 1. Create a dataspace + * \li 2. Use the dataspace to create a dataset in the file or to describe a data array in memory + * \li 3. Modify the dataspace to define dataset elements that will participate in I/O operations + * \li 4. Use the modified dataspace while reading/writing dataset raw data or to create a region reference + * \li 5. Close the dataspace when no longer needed + * + * The rest of this section will address steps 1, 2, and 5 of the programming model; steps 3 and 4 will be + * discussed in later sections of this chapter. + * + *

Creating a Dataspace

+ * + * A dataspace can be created by calling the \ref H5Screate function. Since the + * definition of a simple dataspace requires the specification of dimensionality (or rank) and initial and + * maximum dimension sizes, the HDF5 Library provides a convenience API, \ref H5Screate_simple to create a + * simple dataspace in one step. + * + * The following examples illustrate the usage of these APIs. + * + *

Creating a Scalar Dataspace

+ * + * Creating a Scalar Dataspace + * \code + * hid_t space_id; + * . . . + * space_id = H5Screate(H5S_SCALAR); + * \endcode + * As mentioned above, the dataspace will contain only one element. Scalar dataspaces are used more often + * for describing attributes that have just one value. For example, the attribute temperature with the value + * Celsius is used to indicate that the dataset with this attribute stores temperature values using the + * Celsius scale. + * + *

Creating a Null Dataspace

+ * + * A null dataspace is created with the \ref H5Screate function. + * \code + * hid_t space_id; + * . . . + * space_id = H5Screate(H5S_NULL); + * \endcode + * As mentioned above, the dataspace will contain no elements. + * + *

Creating a Simple Dataspace

+ * + * Let’s assume that an application wants to store a two‐dimensional array of data, A(20,100). During the + * life of the application, the first dimension of the array can grow up to 30; there is no restriction on + * the size of the second dimension. The following steps are used to declare a dataspace for the dataset + * in which the array data will be stored. + * \code + * hid_t space_id; + * int rank = 2; + * hsize_t current_dims[2] = {20, 100}; + * hsize_t max_dims[2] = {30, H5S_UNLIMITED}; + * . . . + * space_id = H5Screate(H5S_NULL); + * H5Sset_extent_simple(space_id, rank, current_dims, max_dims); + * \endcode + * + * Alternatively, the convenience APIs H5Screate_simple/h5screate_simple_f can replace the + * H5Screate/h5screate_f and H5Sset_extent_simple/h5sset_extent_simple_f calls. + * \code + * space_id = H5Screate_simple(rank, current_dims, max_dims); + * \endcode + * + * In this example, a dataspace with current dimensions of 20 by 100 is created. The first dimension can be + * extended only up to 30. The second dimension, however, is declared unlimited; it can be extended up to + * the largest available integer value on the system. + * + * Note that when there is a difference between the current dimensions and the maximum dimensions of an + * array, then chunking storage must be used. In other words, if the number of dimensions may change over + * the life of the dataset, then chunking must be used. If the array dimensions are fixed (if the number of + * current dimensions is equal to the maximum number of dimensions when the dataset is created), then + * contiguous storage can be used. For more information, see "Data Transfer". + * + * Maximum dimensions can be the same as current dimensions. In such a case, the sizes of dimensions + * cannot be changed during the life of the dataspace object. In C, \c NULL can be used to indicate to the + * \ref H5Screate_simple and \ref H5Sset_extent_simple functions that the maximum sizes of all dimensions + * are the same as the current sizes. + * \code + * space_id = H5Screate_simple(rank, current_dims, NULL); + * \endcode + * The created dataspace will have current and maximum dimensions of 20 and 100 correspondingly, and the + * sizes of those dimensions cannot be changed. + * + *

C versus Fortran Dataspaces

+ * + * Dataspace dimensions are numbered from 1 to rank. HDF5 uses C storage conventions, assuming that the + * last listed dimension is the fastest‐changing dimension and the first‐listed dimension is the slowest + * changing. The HDF5 file format storage layout specification adheres to the C convention and the HDF5 + * Library adheres to the same convention when storing dataspace dimensions in the file. This affects how + * C programs and tools interpret data written from Fortran programs and vice versa. The example below + * illustrates the issue. + * + * When a Fortran application describes a dataspace to store an array as A(20,100), it specifies the value of + * the first dimension to be 20 and the second to be 100. Since Fortran stores data by columns, the + * first‐listed dimension with the value 20 is the fastest‐changing dimension and the last‐listed dimension + * with the value 100 is the slowest‐changing. In order to adhere to the HDF5 storage convention, the HDF5 + * Fortran wrapper transposes dimensions, so the first dimension becomes the last. The dataspace dimensions + * stored in the file will be 100,20 instead of 20,100 in order to correctly describe the Fortran data that + * is stored in 100 columns, each containing 20 elements. + * + * When a Fortran application reads the data back, the HDF5 Fortran wrapper transposes the dimensions + * once more, returning the first dimension to be 20 and the second to be 100, describing correctly the sizes + * of the array that should be used to read data in the Fortran array A(20,100). + * + * When a C application reads data back, the dimensions will come out as 100 and 20, correctly describing + * the size of the array to read data into, since the data was written as 100 records of 20 elements each. + * Therefore C tools such as h5dump and h5ls always display transposed dimensions and values for the data + * written by a Fortran application. + * + * Consider the following simple example of equivalent C 3 x 5 and Fortran 5 x 3 arrays. As illustrated in + * the figure below, a C application will store a 3 x 5 2‐dimensional array as three 5‐element rows. In order + * to store the same data in the same order, a Fortran application must view the array as a 5 x 3 array with + * three 5‐element columns. The dataspace of this dataset, as written from Fortran, will therefore be + * described as 5 x 3 in the application but stored and described in the file according to the C convention + * as a 3 x 5 array. This ensures that C and Fortran applications will always read the data in the order in + * which it was written. The HDF5 Fortran interface handles this transposition automatically. + * \code + * // C + * \#define NX 3 // dataset dimensions + * \#define NY 5 + * . . . + * int data[NX][NY]; // data to write + * . . . + * // Data and output buffer initialization. + * for (j = 0; j < NX; j++) + * for (i = 0; i < NY; i++) + * data[j][i] = i + j; + * // + * // 1 2 3 4 5 + * // 6 7 8 9 10 + * // 11 12 13 14 15 + * // + * . . . + * dims[0] = NX; + * dims[1] = NY; + * dataspace = H5Screate_simple(RANK, dims, NULL); + * \endcode + * + * \code + * ! Fortran + * INTEGER, PARAMETER :: NX = 3 + * INTEGER, PARAMETER :: NX = 5 + * . . . + * INTEGER(HSIZE_T), DIMENSION(2) :: dims = (/NY, NX/) ! Dataset dimensions + * . . . + * ! + * ! Initialize data + * ! + * do i = 1, NY + * do j = 1, NX + * data(i,j) = i + (j-1)*NY + * enddo + * enddo + * ! + * ! Data + * ! + * ! 1 6 11 + * ! 2 7 12 + * ! 3 8 13 + * ! 4 9 14 + * ! 5 10 15 + * . . . + * CALL h5screate_simple_f(rank, dims, dspace_id, error) + * \endcode + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Comparing C and Fortran dataspaces
+ * A dataset stored by a C program in a 3 x 5 array: + *
+ * \image html Dspace_CvsF1.gif + *
+ * The same dataset stored by a Fortran program in a 5 x 3 array: + *
+ * \image html Dspace_CvsF2.gif + *
+ * The first dataset above as written to an HDF5 file from C or the second dataset above as written + * from Fortran: + *
+ * \image html Dspace_CvsF3.gif + *
+ * The first dataset above as written to an HDF5 file from Fortran: + *
+ * \image html Dspace_CvsF4.gif + *
+ * + * Note: The HDF5 Library stores arrays along the fastest‐changing dimension. This approach is often + * referred to as being “in C order.” C, C++, and Java work with arrays in row‐major order. In other words, + * the row, or the last dimension, is the fastest‐changing dimension. Fortran, on the other hand, handles + * arrays in column‐major order making the column, or the first dimension, the fastest‐changing dimension. + * Therefore, the C and Fortran arrays illustrated in the top portion of this figure are stored identically + * in an HDF5 file. This ensures that data written by any language can be meaningfully read, interpreted, + * and manipulated by any other. + * + *

Finding Dataspace Characteristics

+ * + * The HDF5 Library provides several APIs designed to query the characteristics of a dataspace. + * + * The function \ref H5Sis_simple returns information about the type of a dataspace. + * This function is rarely used and currently supports only simple and scalar dataspaces. + * + * To find out the dimensionality, or rank, of a dataspace, use \ref H5Sget_simple_extent_ndims. + * \ref H5Sget_simple_extent_dims can also be used to find out the rank. See + * the example below. If both functions return 0 for the value of rank, then the dataspace is scalar. + * + * To query the sizes of the current and maximum dimensions, use \ref H5Sget_simple_extent_dims. + * + * The following example illustrates querying the rank and dimensions of a dataspace using these functions. + * \code + * hid_t space_id; + * int rank; + * hsize_t *current_dims; + * hsize_t *max_dims; + * . . . + * rank = H5Sget_simple_extent_ndims(space_id); + * // (or rank = H5Sget_simple_extent_dims(space_id, NULL, NULL);) + * current_dims = (hsize_t)malloc(rank * sizeof(hsize_t)); + * max_dims = (hsize_t)malloc(rank * sizeof(hsize_t)); + * H5Sget_simple_extent_dims(space_id, current_dims, max_dims); + * // Print values here + * \endcode + * * \subsection subsec_dataspace_transfer Dataspaces and Data Transfer + * + * Read and write operations transfer data between an HDF5 file on disk and in memory. The shape that the + * array data takes in the file and in memory may be the same, but HDF5 also allows users the ability to + * represent data in memory in a different shape than in the file. If the shape of an array in the file and + * in memory will be the same, then the same dataspace definition can be used for both. If the shape of an + * array in memory needs to be different than the shape in the file, then the dataspace definition for the + * shape of the array in memory can be changed. During a read operation, the array will be read into the + * different shape in memory, and during a write operation, the array will be written to the file in the + * shape specified by the dataspace in the file. The only qualification is that the number of elements read + * or written must be the same in both the source and the destination dataspaces. + * + * Item a in the figure below shows a simple example of a read operation in which the data is stored as a 3 + * by 4 array in the file (item b) on disk, but the program wants it to be a 4 by 3 array in memory. This is + * accomplished by setting the memory dataspace to describe the desired memory layout, as in item c. The read + * operation reads the data in the file array into the memory array. + * + * + * + * + * + *
+ * \image html Dspace_read.gif "Data layout before and after a read operation" + *
+ * + * + * + * + * + *
+ * \image html Dspace_move.gif "Moving data from disk to memory" + *
+ + * Both the source and destination are stored as contiguous blocks of storage with the elements in the order + * specified by the dataspace. The figure above shows one way the elements might be organized. In item a, + * the elements are stored as 3 blocks of 4 elements. The destination is an array of 12 elements in memory + * (see item c). As the figure suggests, the transfer reads the disk blocks into a memory buffer (see item b), + * and then writes the elements to the correct locations in memory. A similar process occurs in reverse when + * data is written to disk. + * * \subsubsection subsubsec_dataspace_transfer_select Data Selection + * + * In addition to rearranging data, the transfer may select the data elements from the source and destination. + * + * Data selection is implemented by creating a dataspace object that describes the selected elements (within + * the hyper rectangle) rather than the whole array. Two dataspace objects with selections can be used in + * data transfers to read selected elements from the source and write selected elements to the destination. + * When data is transferred using the dataspace object, only the selected elements will be transferred. + * + * This can be used to implement partial I/O, including: + * \li Sub‐setting ‐ reading part of a large dataset + * \li Sampling ‐ reading selected elements (for example, every second element) of a dataset + * \li Scatter‐gather ‐ read non‐contiguous elements into contiguous locations (gather) or read contiguous + * elements into non‐contiguous locations (scatter) or both + * + * To use selections, the following steps are followed: + * \li 1. Get or define the dataspace for the source and destination + * \li 2. Specify one or more selections for source and destination dataspaces + * \li 3. Transfer data using the dataspaces with selections + * + * A selection is created by applying one or more selections to a dataspace. A selection may override any + * other selections (#H5S_SELECT_SET) or may be “Ored” with previous selections on the same dataspace + * (#H5S_SELECT_OR). In the latter case, the resulting selection is the union of the selection and all + * previously selected selections. Arbitrary sets of points from a dataspace can be selected by specifying + * an appropriate set of selections. + * + * Two selections are used in data transfer, so the source and destination must be compatible, as described + * below. + * + * There are two forms of selection, hyperslab and point. A selection must be either a point selection or a + * set of hyperslab selections. Selections cannot be mixed. + * + * The definition of a selection within a dataspace, not the data in the selection, cannot be saved to the + * file unless the selection definition is saved as a region reference. For more information, + * see \ref subsec_dataspace_refer. + * + *

Hyperslab Selection

+ * + * A hyperslab is a selection of elements from a hyper rectangle. An HDF5 hyperslab is a rectangular pattern + * defined by four arrays. The four arrays are summarized in the table below. + * + * The offset defines the origin of the hyperslab in the original dataspace. + * + * The stride is the number of elements to increment between selected elements. A stride of ‘1’ is every + * element, a stride of ‘2’ is every second element, etc. Note that there may be a different stride for + * each dimen‐sion of the dataspace. The default stride is 1. + * + * The count is the number of elements in the hyperslab selection. When the stride is 1, the selection is a + * hyper rectangle with a corner at the offset and size count[0] by count[1] by.... When stride is greater + * than one, the hyperslab bounded by the offset and the corners defined by stride[n] * count[n]. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Hyperslab elements
+ * Parameter + * + * Description + *
+ * Offset + * + * The starting location for the hyperslab. + *
+ * Stride + * + * The number of elements to separate each element or block to be selected. + *
+ * Count + * + * The number of elements or blocks to select along each dimension. + *
+ * Block + * + * The size of the block selected from the dataspace. + *
+ * + * The block is a count on the number of repetitions of the hyperslab. The default block size is '1', which is + * one hyperslab. A block of 2 would be two hyperslabs in that dimension, with the second starting at + * offset[n] + (count[n] * stride[n]) + 1. + * + * A hyperslab can be used to access a sub‐set of a large dataset. The figure below shows an example of a + * hyperslab that reads a rectangle from the middle of a larger two dimensional array. The destination is the + * same shape as the source. + * + * + * + * + * + *
+ * \image html Dspace_subset.gif "Access a sub‐set of data with a hyperslab" + *
+ * + * Hyperslabs can be combined to select complex regions of the source and destination. The figure below + * shows an example of a transfer from one non‐rectangular region into another non‐rectangular region. The + * source is defined as the union of two hyperslabs, and the destination is the union of three hyperslabs. + * + * + * + * + * + *
+ * \image html Dspace_complex.gif "Build complex regions with hyperslab unions" + *
+ * + * Hyperslabs may also be used to collect or scatter data from regular patterns. The figure below shows an + * example where the source is a repeating pattern of blocks, and the destination is a single, one dimensional + * array. + * + * + * + * + * + *
+ * \image html Dspace_combine.gif "Use hyperslabs to combine or disperse data" + *
+ * + *

Select Points

+ * + * The second type of selection is an array of points such as coordinates. Essentially, this selection is a + * list of all the points to include. The figure below shows an example of a transfer of seven elements from + * a two dimensional dataspace to a three dimensional dataspace using a point selection to specify the points. + * + * + * + * + * + *
+ * \image html Dspace_point.gif "Point selection" + *
+ * + *

Rules for Defining Selections

+ * + * A selection must have the same number of dimensions (rank) as the dataspace it is applied to, although it + * may select from only a small region such as a plane from a 3D dataspace. Selections do not affect the + * extent of the dataspace, the selection may be larger than the dataspace. The boundaries of selections are + * reconciled with the extent at the time of the data transfer. + * + *

Data Transfer with Selections

+ * + * A data transfer (read or write) with selections is the same as any read or write, except the source + * and destination dataspace have compatible selections. + * + * During the data transfer, the following steps are executed by the library: + * \li The source and destination dataspaces are checked to assure that the selections are compatible. + * + * \li The data is transferred, element by element. + * + * Selections have an iteration order for the points selected, which can be any permutation of the dimensions + * involved (defaulting to 'C' array order) or a specific order for the selected points, for selections + * composed of single array elements with \ref H5Sselect_elements. + * + * The elements of the selections are transferred in row‐major, or C order. That is, it is assumed that the + * first dimension varies slowest, the second next slowest, and so forth. For hyperslab selections, the order + * can be any permutation of the dimensions involved (defaulting to ‘C’ array order). When multiple hyperslabs + * are combined, the hyperslabs are coalesced into contiguous reads and writes. + * + * In the case of point selections, the points are read and written in the order specified. + * * \subsubsection subsubsec_dataspace_transfer_model Programming Model + * + * + *

Selecting Hyperslabs

+ * + * Suppose we want to read a 3x4 hyperslab from a dataset in a file beginning at the element <1,2> in the + * dataset, and read it into a 7 x 7 x 3 array in memory. See the figure below. In order to do this, we must + * create a dataspace that describes the overall rank and dimensions of the dataset in the file as well as + * the position and size of the hyperslab that we are extracting from that dataset. + * + * + * + * + * + *
+ * \image html Dspace_select.gif "Selecting a hyperslab" + *
+ * + * The code in the first example below illustrates the selection of the hyperslab in the file dataspace. + * The second example below shows the definition of the destination dataspace in memory. Since the in‐memory + * dataspace has three dimensions, the hyperslab is an array with three dimensions with the last dimension + * being 1: <3,4,1>. The third example below shows the read using the source and destination dataspaces + * with selections. + * + * Selecting a hyperslab + * \code + * //get the file dataspace. + * dataspace = H5Dget_space(dataset); // dataspace identifier + * + * // Define hyperslab in the dataset. + * offset[0] = 1; + * offset[1] = 2; + * count[0] = 3; + * count[1] = 4; + * status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, count, NULL); + * \endcode + * + * Defining the destination memory + * \code + * // Define memory dataspace. + * dimsm[0] = 7; + * dimsm[1] = 7; + * dimsm[2] = 3; + * memspace = H5Screate_simple(3,dimsm,NULL); + * + * // Define memory hyperslab. + * offset_out[0] = 3; + * offset_out[1] = 0; + * offset_out[2] = 0; + * count_out[0] = 3; + * count_out[1] = 4; + * count_out[2] = 1; + * status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL, count_out, NULL); + * \endcode + * + * A sample read specifying source and destination dataspaces + * \code + * ret = H5Dread(dataset, H5T_NATIVE_INT, memspace,dataspace, H5P_DEFAULT, data); + * \endcode + * + *

Example with Strides and Blocks

+ * + * Consider an 8 x 12 dataspace into which we want to write eight 3 x 2 blocks in a two dimensional array + * from a source dataspace in memory that is a 50‐element one dimensional array. See the figure below. + * + * + * + * + * + *
+ * \image html Dspace_write1to2.gif "Write from a one dimensional array to a two dimensional array" + *
+ * + * The example below shows code to write 48 elements from the one dimensional array to the file dataset + * starting with the second element in vector. The destination hyperslab has the following parameters: + * offset=(0,1), stride=(4,3), count=(2,4), block=(3,2). The source has the parameters: offset=(1), + * stride=(1), count=(48), block=(1). After these operations, the file dataspace will have the values + * shown in item b in the figure above. Notice that the values are inserted in the file dataset in + * row‐major order. + * + * Write from a one dimensional array to a two dimensional array + * \code + * // Select hyperslab for the dataset in the file, using 3 x 2 blocks, (4,3) stride (2,4) + * // count starting at the position (0,1). + * offset[0] = 0; offset[1] = 1; + * stride[0] = 4; stride[1] = 3; + * count[0] = 2; count[1] = 4; + * block[0] = 3; block[1] = 2; + * ret = H5Sselect_hyperslab(fid, H5S_SELECT_SET, offset, stride, count, block); + * + * // Create dataspace for the first dataset. + * mid1 = H5Screate_simple(MSPACE1_RANK, dim1, NULL); + * + * // Select hyperslab. + * // We will use 48 elements of the vector buffer starting + * // at the second element. Selected elements are + * // 1 2 3 . . . 48 + * offset[0] = 1; + * stride[0] = 1; + * count[0] = 48; + * block[0] = 1; + * ret = H5Sselect_hyperslab(mid1, H5S_SELECT_SET, offset, stride, count, block); + * + * // Write selection from the vector buffer to the dataset in the file. + * ret = H5Dwrite(dataset, H5T_NATIVE_INT, midd1, fid, H5P_DEFAULT, vector) + * \endcode + * + *

Selecting a Union of Hyperslabs

+ * + * The HDF5 Library allows the user to select a union of hyperslabs and write or read the selection into + * another selection. The shapes of the two selections may differ, but the number of elements must be + * equal. + * + * + * + * + * + *
+ * \image html Dspace_transfer.gif "Transferring hyperslab unions" + *
+ * + * The figure above shows the transfer of a selection that is two overlapping hyperslabs from the dataset + * into a union of hyperslabs in the memory dataset. Note that the destination dataset has a different shape + * from the source dataset. Similarly, the selection in the memory dataset could have a different shape than + * the selected union of hyperslabs in the original file. For simplicity, the selection is that same shape + * at the destination. + * + * To implement this transfer, it is necessary to: + * \li 1. Get the source dataspace + * \li 2. Define one hyperslab selection for the source + * \li 3. Define a second hyperslab selection, unioned with the first + * \li 4. Get the destination dataspace + * \li 5. Define one hyperslab selection for the destination + * \li 6. Define a second hyperslab seletion, unioned with the first + * \li 7. Execute the data transfer (H5Dread or H5Dwrite) using the source and destination dataspaces + * + * The example below shows example code to create the selections for the source dataspace (the file). The + * first hyperslab is size 3 x 4 and the left upper corner at the position (1,2). The hyperslab is a simple + * rectangle, so the stride and block are 1. The second hyperslab is 6 x 5 at the position (2,4). The second + * selection is a union with the first hyperslab (#H5S_SELECT_OR). + * + * Select source hyperslabs + * \code + * fid = H5Dget_space(dataset); + * + * // Select first hyperslab for the dataset in the file. + * offset[0] = 1; offset[1] = 2; + * block[0] = 1; block[1] = 1; + * stride[0] = 1; stride[1] = 1; + * count[0] = 3; count[1] = 4; + * ret = H5Sselect_hyperslab(fid, H5S_SELECT_SET, offset, stride, count, block); + * + * // Add second selected hyperslab to the selection. + * offset[0] = 2; offset[1] = 4; + * block[0] = 1; block[1] = 1; + * stride[0] = 1; stride[1] = 1; + * count[0] = 6; count[1] = 5; + * ret = H5Sselect_hyperslab(fid, H5S_SELECT_OR, offset, stride, count, block); + * \endcode + * + * The example below shows example code to create the selection for the destination in memory. The steps + * are similar. In this example, the hyperslabs are the same shape, but located in different positions in the + * dataspace. The first hyperslab is 3 x 4 and starts at (0,0), and the second is 6 x 5 and starts at (1,2). + * Finally, the H5Dread call transfers the selected data from the file dataspace to the selection in memory. + * In this example, the source and destination selections are two overlapping rectangles. In general, any + * number of rectangles can be OR’ed, and they do not have to be contiguous. The order of the selections + * does not matter, but the first should use #H5S_SELECT_SET ; subsequent selections are unioned using + * #H5S_SELECT_OR. + * + * It is important to emphasize that the source and destination do not have to be the same shape (or number + * of rectangles). As long as the two selections have the same number of elements, the data can be + * transferred. + * + * Select destination hyperslabs + * \code + * // Create memory dataspace. + * mid = H5Screate_simple(MSPACE_RANK, mdim, NULL); + * + * // Select two hyperslabs in memory. Hyperslabs has the + * // same size and shape as the selected hyperslabs for + * // the file dataspace. + * offset[0] = 0; offset[1] = 0; + * block[0] = 1; block[1] = 1; + * stride[0] = 1; stride[1] = 1; + * count[0] = 3; count[1] = 4; + * ret = H5Sselect_hyperslab(mid, H5S_SELECT_SET, offset, stride, count, block); + * + * offset[0] = 1; offset[1] = 2; + * block[0] = 1; block[1] = 1; + * stride[0] = 1; stride[1] = 1; + * count[0] = 6; count[1] = 5; + * ret = H5Sselect_hyperslab(mid, H5S_SELECT_OR, offset, stride, count, block); + * + * ret = H5Dread(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, matrix_out); + * \endcode + * + *

Selecting a List of Independent Points

+ * + * It is also possible to specify a list of elements to read or write using the function H5Sselect_elements. + * + * The procedure is similar to hyperslab selections. + * \li 1. Get the source dataspace + * \li 2. Set the selected points + * \li 3. Get the destination dataspace + * \li 4. Set the selected points + * \li 5. Transfer the data using the source and destination dataspaces + * + * The figure below shows an example where four values are to be written to four separate points in a two + * dimensional dataspace. The source dataspace is a one dimensional array with the values 53, 59, 61, 67. + * The destination dataspace is an 8 x 12 array. The elements are to be written to the points + * (0,0), (3,3), (3,5), and (5,6). In this example, the source does not require a selection. The example + * below the figure shows example code to implement this transfer. + * + * A point selection lists the exact points to be transferred and the order they will be transferred. The + * source and destination are required to have the same number of elements. A point selection can be used + * with a hyperslab (for example, the source could be a point selection and the destination a hyperslab, + * or vice versa), so long as the number of elements selected are the same. + * + * + * + * + * + *
+ * \image html Dspace_separate.gif "Write data to separate points" + *
+ * + * Write data to separate points + * \code + * hsize_t dim2[] = {4}; + * int values[] = {53, 59, 61, 67}; + * + * // file dataspace + * hssize_t coord[4][2]; + * + * // Create dataspace for the second dataset. + * mid2 = H5Screate_simple(1, dim2, NULL); + * + * // Select sequence of NPOINTS points in the file dataspace. + * coord[0][0] = 0; coord[0][1] = 0; + * coord[1][0] = 3; coord[1][1] = 3; + * coord[2][0] = 3; coord[2][1] = 5; + * coord[3][0] = 5; coord[3][1] = 6; + * + * ret = H5Sselect_elements(fid, H5S_SELECT_SET, NPOINTS, (const hssize_t **)coord); + * + * ret = H5Dwrite(dataset, H5T_NATIVE_INT, mid2, fid, H5P_DEFAULT, values); + * \endcode + * + *

Combinations of Selections

+ * + * Selections are a very flexible mechanism for reorganizing data during a data transfer. With different + * combinations of dataspaces and selections, it is possible to implement many kinds of data transfers + * including sub‐setting, sampling, and reorganizing the data. The table below gives some example combinations + * of source and destination, and the operations they implement. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Selection operations
+ *

Source

+ *
+ *

Destination

+ *
+ *

Operation

+ *
+ *

All

+ *
+ *

All

+ *
+ *

Copy whole array

+ *
+ *

All

+ *
+ *

All (different shape)

+ *
+ *

Copy and reorganize array

+ *
+ *

Hyperslab

+ *
+ *

All

+ *
+ *

Sub-set

+ *
+ *

Hyperslab

+ *
+ *

Hyperslab (same shape)

+ *
+ *

Selection

+ *
+ *

Hyperslab

+ *
+ *

Hyperslab (different shape)

+ *
+ *

Select and rearrange

+ *
+ *

Hyperslab with stride or block

+ *
+ *

All or hyperslab with stride 1

+ *
+ *

Sub-sample, scatter

+ *
+ *

Hyperslab

+ *
+ *

Points

+ *
+ *

Scatter

+ *
+ *

Points

+ *
+ *

Hyperslab or all

+ *
+ *

Gather

+ *
+ *

Points

+ *
+ *

Points (same)

+ *
+ *

Selection

+ *
+ *

Points

+ *
+ *

Points (different)

+ *
+ *

Reorder points

+ *
+ * * \subsection subsec_dataspace_select Dataspace Selection Operations and Data Transfer + * + * This section is under construction. + * * \subsection subsec_dataspace_refer References to Dataset Regions + * + * Another use of selections is to store a reference to a region of a dataset. An HDF5 object reference + * object is a pointer to an object (dataset, group, or committed datatype) in the file. A selection can + * be used to create a pointer to a set of selected elements of a dataset, called a region reference. The + * selection can be either a point selection or a hyperslab selection. + * + * A region reference is an object maintained by the HDF5 Library. The region reference can be stored in a + * dataset or attribute, and then read. The dataset or attribute is defined to have the special datatype, + * #H5T_STD_REF_DSETREG. + * + * To discover the elements and/or read the data, the region reference can be dereferenced. The + * #H5Rdereference call returns an identifier for the dataset, and then the selected dataspace can be + * retrieved with a call to #H5Rget_region(). The selected dataspace can be used to read the selected data + * elements. + * + * For more information, \see subsubsec_datatype_other_refs. + * * \subsubsection subsubsec_dataspace_refer_use Example Uses for Region References + * + * Region references are used to implement stored pointers to data within a dataset. For example, features + * in a large dataset might be indexed by a table. See the figure below. This table could be stored as an + * HDF5 dataset with a compound datatype, for example, with a field for the name of the feature and a region + * reference to point to the feature in the dataset. See the second figure below. + * + * + * + * + * + *
+ * \image html Dspace_features.gif " Features indexed by a table" + *
+ * + * + * + * + * + *
+ * \image html Dspace_features_cmpd.gif "Storing the table with a compound datatype" + *
+ * + * * \subsubsection subsubsec_dataspace_refer_create Creating References to Regions + * + * To create a region reference: + * \li 1. Create or open the dataset that contains the region + * \li 2. Get the dataspace for the dataset + * \li 3. Define a selection that specifies the region + * \li 4. Create a region reference using the dataset and dataspace with selection + * \li 5. Write the region reference(s) to the desired dataset or attribute + * + * The figure below shows a diagram of a file with three datasets. Dataset D1 and D2 are two dimensional + * arrays of integers. Dataset R1 is a one dimensional array of references to regions in D1 and D2. The + * regions can be any valid selection of the dataspace of the target dataset. + * + * + * + * + *
+ * \image html Dspace_three_datasets.gif "A file with three datasets" + *
+ * Note: In the figure above, R1 is a 1 D array of region pointers; each pointer refers to a selection + * in one dataset. + * + * The example below shows code to create the array of region references. The references are created in an + * array of type #hdset_reg_ref_t. Each region is defined as a selection on the dataspace of the dataset, + * and a reference is created using \ref H5Rcreate(). The call to \ref H5Rcreate() specifies the file, + * dataset, and the dataspace with selection. + * + * Create an array of region references + * \code + * // create an array of 4 region references + * hdset_reg_ref_t ref[4]; + * + * // Create a reference to the first hyperslab in the first Dataset. + * offset[0] = 1; offset[1] = 1; + * count[0] = 3; count[1] = 2; + * status = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, offset, NULL, count, NULL); + * status = H5Rcreate(&ref[0], file_id, "D1", H5R_DATASET_REGION, space_id); + * + * // The second reference is to a union of hyperslabs in the first Dataset + * offset[0] = 5; offset[1] = 3; + * count[0] = 1; count[1] = 4; + * status = H5Sselect_none(space_id); + * status = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, offset, NULL, count, NULL); + * offset[0] = 6; offset[1] = 5; + * count[0] = 1; count[1] = 2; + * status = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, offset, NULL, count, NULL); + * status = H5Rcreate(&ref[1], file_id, "D1", H5R_DATASET_REGION, space_id); + * + * // the fourth reference is to a selection of points in the first Dataset + * status = H5Sselect_none(space_id); + * coord[0][0] = 4; coord[0][1] = 4; + * coord[1][0] = 2; coord[1][1] = 6; + * coord[2][0] = 3; coord[2][1] = 7; + * coord[3][0] = 1; coord[3][1] = 5; + * coord[4][0] = 5; coord[4][1] = 8; + * + * status = H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hssize_t **)coord); + * status = H5Rcreate(&ref[3], file_id, "D1", H5R_DATASET_REGION, space_id); + * + * // the third reference is to a hyperslab in the second Dataset + * offset[0] = 0; offset[1] = 0; + * count[0] = 4; count[1] = 6; + * status = H5Sselect_hyperslab(space_id2, H5S_SELECT_SET, offset, NULL, count, NULL); + * status = H5Rcreate(&ref[2], file_id, "D2", H5R_DATASET_REGION, space_id2); + * \endcode + * + * When all the references are created, the array of references is written to the dataset R1. The + * dataset is declared to have datatype #H5T_STD_REF_DSETREG. See the example below. + * + * Write the array of references to a dataset + * \code + * Hsize_t dimsr[1]; + * dimsr[0] = 4; + * + * // Dataset with references. + * spacer_id = H5Screate_simple(1, dimsr, NULL); + * dsetr_id = H5Dcreate(file_id, "R1", H5T_STD_REF_DSETREG, spacer_id, H5P_DEFAULT, H5P_DEFAULT, + * H5P_DEFAULT); + * + * // Write dataset with the references. + * status = H5Dwrite(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref); + * + * \endcode + * + * When creating region references, the following rules are enforced. + * \li The selection must be a valid selection for the target dataset, just as when transferring data + * \li The dataset must exist in the file when the reference is created; #H5Rcreate + * \li The target dataset must be in the same file as the stored reference + * * \subsubsection subsubsec_dataspace_refer_read Reading References to Regions + * + * To retrieve data from a region reference, the reference must be read from the file, and then the data can + * be retrieved. The steps are: + * \li 1. Open the dataset or attribute containing the reference objects + * \li 2. Read the reference object(s) + * \li 3. For each region reference, get the dataset (#H5Rdereference) and dataspace (#H5Rget_region) + * \li 4. Use the dataspace and datatype to discover what space is needed to store the data, allocate the + * correct storage and create a dataspace and datatype to define the memory data layout + * + * The example below shows code to read an array of region references from a dataset, and then read the + * data from the first selected region. Note that the region reference has information that records the + * dataset (within the file) and the selection on the dataspace of the dataset. After dereferencing the + * regions reference, the datatype, number of points, and some aspects of the selection can be discovered. + * (For a union of hyperslabs, it may not be possible to determine the exact set of hyperslabs that has been + * combined.) + * The table below the code example shows the inquiry functions. + * + * When reading data from a region reference, the following rules are enforced: + * \li The target dataset must be present and accessible in the file + * \li The selection must be a valid selection for the dataset + * + * Read an array of region references; read from the first selection + * \code + * dsetr_id = H5Dopen (file_id, "R1", H5P_DEFAULT); + * status = H5Dread(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_out); + * + * // Dereference the first reference. + * // 1) get the dataset (H5Rdereference) + * // 2) get the selected dataspace (H5Rget_region) + * + * dsetv_id = H5Rdereference(dsetr_id, H5R_DATASET_REGION, &ref_out[0]); + * space_id = H5Rget_region(dsetr_id, H5R_DATASET_REGION, &ref_out[0]); + * + * // Discover how many points and shape of the data + * ndims = H5Sget_simple_extent_ndims(space_id); + * H5Sget_simple_extent_dims(space_id,dimsx,NULL); + * + * // Read and display hyperslab selection from the dataset. + * dimsy[0] = H5Sget_select_npoints(space_id); + * spacex_id = H5Screate_simple(1, dimsy, NULL); + * + * status = H5Dread(dsetv_id, H5T_NATIVE_INT, H5S_ALL, space_id, H5P_DEFAULT, data_out); + * printf("Selected hyperslab: "); + * for (i = 0; i < 8; i++) { + * printf("\n"); + * for (j = 0; j < 10; j++) + * printf("%d ", data_out[i][j]); + * } + * printf("\n"); + * \endcode + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
The inquiry functions
+ *

Function

+ *
+ *

Information

+ *
+ * @ref H5Sget_select_npoints + * + *

The number of elements in the selection (hyperslab or point selection).

+ *
+ * @ref H5Sget_select_bounds + * + *

The bounding box that encloses the selected points (hyperslab or point selection).

+ *
+ * @ref H5Sget_select_hyper_nblocks + * + *

The number of blocks in the selection.

+ *
+ * @ref H5Sget_select_hyper_blocklist + * + *

A list of the blocks in the selection.

+ *
+ * @ref H5Sget_select_elem_npoints + * + *

The number of points in the selection.

+ *
+ * @ref H5Sget_select_elem_pointlist + * + *

The points.

+ *
+ * + * * \subsection subsec_dataspace_sample Sample Programs * + * This section contains the full programs from which several of the code examples in this chapter were + * derived. The h5dump output from the program’s output file immediately follows each program. + * + * h5_write.c + * \code + * #include "hdf5.h" + * + * #define H5FILE_NAME "SDS.h5" + * #define DATASETNAME "C Matrix" + * #define NX 3 + * #define NY 5 + * #define RANK 2 // dataset dimensions + * + * int + * main (void) + * { + * hid_t file, dataset; // file and dataset identifiers + * hid_t datatype, dataspace; // identifiers + * hsize_t dims[2]; // dataset dimensions + * herr_t status; + * int data[NX][NY]; // data to write + * int i, j; + * + * // + * // Data and output buffer initialization. + * for (j = 0; j < NX; j++) { + * for (i = 0; i < NY; i++) + * data[j][i] = i + 1 + j*NY; + * } + * // 1 2 3 4 5 + * // 6 7 8 9 10 + * // 11 12 13 14 15 + * + * // Create a new file using H5F_ACC_TRUNC access, + * // default file creation properties, and default file + * // access properties. + * file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + * + * // Describe the size of the array and create the data space for fixed + * // size dataset. + * dims[0] = NX; + * dims[1] = NY; + * dataspace = H5Screate_simple(RANK, dims, NULL); + * + * // Create a new dataset within the file using defined dataspace and + * // datatype and default dataset creation properties. + * dataset = H5Dcreate(file, DATASETNAME, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + * H5P_DEFAULT, H5P_DEFAULT); + * + * // Write the data to the dataset using default transfer properties. + * status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); + * + * // Close/release resources. + * H5Sclose(dataspace); + * H5Dclose(dataset); + * H5Fclose(file); + * + * return 0; + * } + * + * SDS.out + * ------- + * HDF5 "SDS.h5" { + * GROUP "/" { + * DATASET "C Matrix" { + * DATATYPE H5T_STD_I32BE + * DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) } + * DATA { + * 1, 2, 3, 4, 5, + * 6, 7, 8, 9, 10, + * 11, 12, 13, 14, 15 + * } + * } + * + * \endcode + * + * h5_write.f90 + * \code + * ---------- + * PROGRAM DSETEXAMPLE + * + * USE HDF5 ! This module contains all necessary modules + * + * IMPLICIT NONE + * + * CHARACTER(LEN=7), PARAMETER :: filename = "SDSf.h5" ! File name + * CHARACTER(LEN=14), PARAMETER :: dsetname = "Fortran Matrix" ! Dataset name + * INTEGER, PARAMETER :: NX = 3 + * INTEGER, PARAMETER :: NY = 5 + * + * INTEGER(HID_T) :: file_id ! File identifier + * INTEGER(HID_T) :: dset_id ! Dataset identifier + * INTEGER(HID_T) :: dspace_id ! Dataspace identifier + * + * INTEGER(HSIZE_T), DIMENSION(2) :: dims = (/3,5/) ! Dataset dimensions + * INTEGER :: rank = 2 ! Dataset rank + * INTEGER :: data(NX,NY) + * INTEGER :: error ! Error flag + * INTEGER :: i, j + * + * ! + * ! Initialize data + * ! + * do i = 1, NX + * do j = 1, NY + * data(i,j) = j + (i-1)*NY + * enddo + * enddo + * ! + * ! Data + * ! + * ! 1 2 3 4 5 + * ! 6 7 8 9 10 + * ! 11 12 13 14 15 + * + * ! + * ! Initialize FORTRAN interface. + * ! + * CALLh5open_f(error) + * + * ! + * ! Create a new file using default properties. + * ! + * CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error) + * + * ! + * ! Create the dataspace. + * ! + * CALL h5screate_simple_f(rank, dims, dspace_id, error) + * + * ! + * ! Create and write dataset using default properties. + * ! + * CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, dspace_id, & + * dset_id, error, H5P_DEFAULT_F, H5P_DEFAULT_F, & + * H5P_DEFAULT_F) + * + * CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, data, dims, error) + * + * ! + * ! End access to the dataset and release resources used by it. + * ! + * CALL h5dclose_f(dset_id, error) + * + * ! + * ! Terminate access to the data space. + * ! + * CALL h5sclose_f(dspace_id, error) + * + * ! + * ! Close the file. + * ! + * CALL h5fclose_f(file_id, error) + * + * ! + * ! Close FORTRAN interface. + * ! + * CALL h5close_f(error) + * + * END PROGRAM DSETEXAMPLE + * + * SDSf.out + * -------- + * HDF5 "SDSf.h5" { + * GROUP "/" { + * DATASET "Fortran Matrix" { + * DATATYPE H5T_STD_I32BE + * DATASPACE SIMPLE { ( 5, 3 ) / ( 5, 3 ) } + * DATA { + * 1, 6, 11, + * 2, 7, 12, + * 3, 8, 13, + * 4, 9, 14, + * 5, 10, 15 + * } + * } + * } + * } + * + * \endcode + * + * h5_write_tr.f90 + * \code + * PROGRAM DSETEXAMPLE + * + * USE HDF5 ! This module contains all necessary modules + * + * IMPLICIT NONE + * + * CHARACTER(LEN=10), PARAMETER :: filename = "SDSf_tr.h5" ! File name + * CHARACTER(LEN=24), PARAMETER :: dsetname = "Fortran Transpose Matrix"! Dataset name + * + * INTEGER, PARAMETER :: NX = 3 + * INTEGER, PARAMETER :: NY = 5 + * + * INTEGER(HID_T) :: file_id ! File identifier + * INTEGER(HID_T) :: dset_id ! Dataset identifier + * INTEGER(HID_T) :: dspace_id ! Dataspace identifier + * + * INTEGER(HSIZE_T), DIMENSION(2) :: dims = (/NY, NX/) ! Dataset dimensions + * INTEGER :: rank = 2 ! Dataset rank + * INTEGER :: data(NY,NX) + * + * INTEGER :: error ! Error flag + * INTEGER :: i, j + * + * ! + * ! Initialize data + * ! + * do i = 1, NY + * do j = 1, NX + * data(i,j) = i + (j-1)*NY + * enddo + * enddo + * + * ! + * ! Data + * ! + * ! 1 6 11 + * ! 2 7 12 + * ! 3 8 13 + * ! 4 9 14 + * ! 5 10 15 + * + * ! + * ! Initialize FORTRAN interface. + * ! + * CALL h5open_f(error) + * + * ! + * ! Create a new file using default properties. + * ! + * CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error) + * + * ! + * ! Create the dataspace. + * ! + * CALL h5screate_simple_f(rank, dims, dspace_id, error) + * + * ! + * ! Create and write dataset using default properties. + * ! + * CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, dspace_id, & + * dset_id, error, H5P_DEFAULT_F, H5P_DEFAULT_F, & + * H5P_DEFAULT_F) + * CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, data, dims, error) + * + * ! + * ! End access to the dataset and release resources used by it. + * ! + * CALL h5dclose_f(dset_id, error) + * + * ! + * ! Terminate access to the data space. + * ! + * CALL h5sclose_f(dspace_id, error) + * + * ! + * ! Close the file. + * ! + * CALL h5fclose_f(file_id, error) + * + * ! + * ! Close FORTRAN interface. + * ! + * CALL h5close_f(error) + * + * END PROGRAM DSETEXAMPLE + * + * SDSf_tr.out + * ----------- + * HDF5 "SDSf_tr.h5" { + * GROUP "/" { + * DATASET "Fortran Transpose Matrix" { + * DATATYPE H5T_STD_I32LE + * DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) } + * DATA { + * 1, 2, 3, 4, 5, + * 6, 7, 8, 9, 10, + * 11, 12, 13, 14, 15 + * } + * } + * } + * } + * + * \endcode + * + * Previous Chapter \ref sec_datatype - Next Chapter \ref sec_attribute + * */ /**\defgroup H5S H5S Dataspaces @@ -62,6 +1528,7 @@ * using \Emph{selections}. Furthermore, certain set operations are supported * for selections. * + * */ #endif /* H5Smodule_H */ -- cgit v0.12