HDF5中嵌套的复合数据类型
Nested compound datatypes in HDF5
我是C++应用程序团队的一员,该应用程序处理各种类型的消息并以各种格式输出这些消息。出于本讨论的目的,可以将消息视为名称-值对的集合。这些值通常是数字,但也可以是字符串。消息的结构基本上是在处理过程中发现的消息可以任意大,因此不允许在内存中存储表示。一条消息一次处理一个名称值对消息可以具有内部结构,该结构由名称-值对中的名称捕获。一个很好的类比是在目录层次结构中考虑文件名。
我正在开发一个子系统来处理这些消息,并使用低级HDF5 API来产生HDF输出。由于我上面描述的限制,我使用的方法涉及对一条消息进行两次传递。在第一步中,我收集布局信息并构建一个复合数据类型和一个数据集。然后,我对消息进行第二次传递,以写出值。因为我一次写出一个值,所以我有一个这样的序列:
// name, value, dataType, dtSize, ctDataSet and ctSpace have been defined elsewhere
hid_t valueDT = H5Tcreate(H5T_COMPOUND, dtSize);
herr_t status = H5Tinsert(valueDT, name, 0, dataType);
hid_t filespace = H5Dget_space(ctDataSet);
hsize_t offset[] = { 0 };
hsize_t dim[] = [ 1 };
status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL,
dim, NULL);
status = H5Dwrite(ctDataSet, valueDT, ctSpace, filespace, H5P_DEFAULT, &value);
我已经完成了这项工作,现在我正在尝试将其扩展到处理嵌套的复合数据类型。我已经完成了第一个步骤,但我在第二个步骤上遇到了困难。代码段中的代码构建了一个与值相关的独立数据类型,为其提供了一个对应于数据集中现有字段的名称,然后诱使HDF5将该值作为数据集的一部分写入我意识到我对所用的名字并不明确。假设我们正在查看位置中的字段x。使用的名称将是位置.x。
当值属于内部复合数据类型时,我很困惑如何建立这种关联。如有任何见解,我们将不胜感激。
您需要在每个嵌套级别创建正确的HDF5数据类型,从底部开始。然后,一旦您可以使用总复合数据类型创建数据集,并继续将数据写入文件。
除了在Common Lisp中使用HDF5之外,我刚刚完成了类似的操作。我最终做的是定义一个类型规范(听起来像你的消息)来完全描述数据类型的结构,然后使用记忆(记忆函数输出的花哨单词)生成C结构。
举个例子:假设您有以下结构(伪代码):
Type = {
x of Xtype;
y of Ytype;
}
您可以通过为Type创建复合数据类型
- 为Xtype创建HDF5数据类型(这是递归的,应该被存储)
- 为Ytype创建HDF5数据类型(如下)
- 使用Xtype和Ytype的HDF5数据类型为Type创建HDF5数据型
不过,这确实需要在第一次传递过程中完全确定数据类型的结构,但这听起来不像是处理方式的问题
为了扩展示例,您需要做的是
- 获取复合结构的数据类型规范列表
- (递归)为每个类型规范生成HDF5数据类型
- 根据生成的HDF5数据类型组装总的HDF5复合类型
将数据填充到(递归)复合结构中
对此,通常有两种方法。
源代码生成
您可以创建用于在第一次传递数据期间访问/填充结构的代码。如果你想编写了解C/C++结构和类的代码,这是必要的,因为数据类型是静态的,所以如果一个类型在编译时不存在,那么它在运行时就不可能存在。因此,您可以通过生成C++代码使该类型在编译时存在,然后对其进行编译,然后作为第二遍运行
对于您正在做的事情来说,这种方法听起来不太有前景,因为听起来您将处理相当大的消息流,这将需要相当多的代码生成和编译。因此,转到下一个方法:
原始二进制数据访问
这种方法完全取消了对结构使用静态类型,从而消除了生成C/C++复合类型的要求。
您所做的是使用有关数据类型的信息来计算复合数据类型的总大小,以及类型成员应出现在总类型的内存块中的偏移量。这可以像生成HDF5类型一样递归地完成。
示例:如果你有复合型
Type = {
x of Xtype;
y of Ytype;
}
你会
通过递归下降到Type的结构中得到
Type
的总大小,并以相同的方式将下降到其结构中得到的Xtype
和Ytype
的大小相加。分配内存中
Type
字节的大小。获取将组成
Type
对象的所有基本结构元素的偏移量。如果Xtype
是化合物,那么你必须得到Xtype
的成员,如果其中任何一个是化合物,你就得到它的成员,等等。将每个基本结构元素以适当的偏移量写入分配的内存中。这也必须递归地进行,因为
Xtype
和Ytype
可以是复合类型。
这种方法之所以有效,是因为(至少从程序员的角度来看)数据是连续分配的,因此x
和y
并排放置在分配的内存中。
在这种方法中,您不得不取消结构/类的便利性,但这就是编译器在幕后管理结构/类。
我最终尝试了一种与我最初描述的方法根本不同的方法。我没有尝试将消息映射到复合数据类型上,而是创建了一个顶级的组,并为消息中的每个字段创建一个数据集。在处理消息的后续实例时,我会更改每个数据集的范围。在消息字段是可选的情况下,我在数据集上设置一个属性,以确定哪些消息实例具有与其关联的值。
令我有些惊讶的是,在给定相同输入的情况下,"多数据集"方法会比"复合数据集"方式产生更大的输出文件。我天真的期望是它会更小,但如果我错过了使用API的微妙之处,我也不会感到惊讶。然而,还有一个更令人烦恼的问题。输出文件的使用者将使用MATLAB读取它们MATLAB确实有一些高级函数来读取HDF5文件,特别是h5read()。实现h5read()时,其参数之一是要提取的数据集的名称。我真的不想让用户单独提取他们可能感兴趣的每个数据集。有人能想出一种合理的方法将顶级组封装在数据集中中吗?
- 防止主数据类型C++的隐式转换
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在C++中打印指向不同基元数据类型的指针的内存地址
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何计算数据类型的范围,例如int
- C++中数据类型修饰符的顺序
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 特定数据类型的模板类
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- H5Tget_member_type() 返回复合 HDF5 数据类型的奇怪值
- HDF5-写入/附加HDF5复合数据类型一一带有HyperSlab
- 使用GlclearBufferdata用于复合数据类型的便携式
- C++ HDF5 提取复合数据类型的一个成员
- c++hdf5:如何设计易于扩展到新的复合数据类型的程序
- HDF5中嵌套的复合数据类型
- 隐藏复合数据类型的某些字段,使其不被写入(或从hdf5文件中读取)
- 从HDF5中读取复合数据类型的字符串
- 是否有办法在当前类中打印复合数据类型的所有属性?