HDF5:将线性数组保存到三维数据集

Posted

技术标签:

【中文标题】HDF5:将线性数组保存到三维数据集【英文标题】:HDF5: Saving a linear array to three dimensional dataset 【发布时间】:2013-11-23 07:38:51 【问题描述】:

我在将线性数组从 c++ 保存到 hdf5 文件中的三维数据集时遇到了一个小问题。

内存中的布局是这样的:

    |---+---+---+---+---+---+---+---+---+---+----+----|
    | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    |---+---+---+---+---+---+---+---+---+---+----+----|

虽然它是这样被程序解释的:

         x
    |---+---+---| 
    | 0 | 1 | 2 |
z=0 |---+---+---| y
    | 3 | 4 | 5 |     
    |---+---+---|

           x
    |---+----+----|
    | 6 |  7 |  8 |
z=1 |---+----+----|  y
    | 9 | 10 | 11 |
    |---+----+----|

使用以下代码,将此数组保存到 HDF5 文件中的三维数据集

std::vector<int> buffer;
for(int i = 0; i < 12; ++i)
   buffer.push_back(i);
hsize_t dims[3] = 2,3,2;
    hisze_t mem_dim[1] = 12;
hid_t file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    hid_t space = H5Screate_simple (3, dims, NULL);
hid_t mem_space = H5Screate_simple(1,mem_dim,NULL);

hid_t dset = H5Dcreate (file, DATASET, H5T_STD_I32LE, space, H5P_DEFAULT,
                       H5P_DEFAULT, H5P_DEFAULT);
herr_t status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, space, H5P_DEFAULT,
                   &buffer[0]);

这会导致这样的布局:

         x
   |---+---+----|      
   | 0 | 2 |  4 |
z=0|---+---+----| y
   | 6 | 8 | 10 |
   |---+---+----|

         x
   |---+----+----|
   | 1 |  3 |  5 |
z=1|---+----+----|  y
   | 7 | 9  | 11 |
   |---+----+----|

我猜这是因为行主要格式(z 是变化最快的索引)。无论如何,是否可以通过一次 H5DWrite 调用强制 hdf5 写入预期格式?

我想出了这个主意,但它不起作用。我想我弄错了 hyperslaps 的功能。

    ... //Same as above, but before H5DWrite
    hsize_t start[3];
    hsize_t stride[3];
    hsize_t count[3];
    hsize_t block[3];

    //Select two blocks from array. First for z=0, second for z=1
    start[0] = 0;
    stride[0] = 6;
    count[0] = 2;
    block[0] = 6;
    status = H5Sselect_hyperslab (mem_space, H5S_SELECT_SET, start, stride, count,
             block);

    start[0] = 0;
    start[1] = 0;
    start[2] = 0;

    stride[0] = 2;
    stride[1] = 3;
    stride[2] = 1;

    count[0] = 1;
    count[1] = 1;
    count[2] = 2;

    block[0] = 2;
    block[1] = 3;
    block[2] = 1;

    status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, stride, count,
             block);

    status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, space, H5P_DEFAULT,
                      &buffer[0]);

在我对 H5Sselect_hyperslab 的解释中,定义了两个块 mem_space 映射到文件空间的两个块。但 实际上结果与上面描述的相同。可能吗 在不重新格式化数组的情况下实现预期的行为和 不循环调用 H5DWrite? 我

【问题讨论】:

【参考方案1】:

Hyperslabs 只能跳过单元​​格,不能重新排序。所以我觉得你运气不好。

如你所说,有两种解决方案:

    重新排列文件中的数组。新的维度是:

    hsize_t dims[3] = 2,2,3;
                       ^ ^ ^
                       z i j
    

    然后你可以在一次写入中转储数组。

    在循环中一个接一个地写入数组。

在内存中重新排序数组会浪费时间。

【讨论】:

好吧,我已经通过在一个循环中逐个地编写数组来做到这一点,但我认为只需一次调用 H5Dwrite 就可以实现。顺便说一句。实际上我不这么认为,因为我在内存空间上做了一个选择,在文件空间上做了一个选择。

以上是关于HDF5:将线性数组保存到三维数据集的主要内容,如果未能解决你的问题,请参考以下文章

HDF5:如何将数据附加到数据集(可扩展数组)

如何从 hdf5 保存/提取数据集并转换为 TiFF?

将浮点数组写入和附加到 C++ 中 hdf5 文件中的唯一数据集

编写并将float数组附加到C ++中hdf5文件中的唯一数据集

用于创建 HDF5 数据集的 4 维 c++ 数组的动态内存分配

如何使用 Fortran API 将字符串数组写入 HDF5 数据集?