理解HDF5的块状存储

5

首先,先原谅我的非常基础的问题:我正在学习教程,并成功地编写了我的第一个HDF5数据集。现在,我要开始使用slab,但是我发现做这个有点困难。

据我所知,我需要获得有效的内存空间,选择一个slab,然后写入我的数据。但显然我做错了什么,因为我遇到了错误:

HDF5-DIAG: Error detected in HDF5 (1.8.14) thread 0:
  #000: H5Dio.c line 271 in H5Dwrite(): can't prepare for writing data
    major: Dataset
    minor: Write failed
  #001: H5Dio.c line 352 in H5D__pre_write(): can't write data
    major: Dataset
    minor: Write failed
  #002: H5Dio.c line 690 in H5D__write(): src and dest data spaces have different sizes
    major: Invalid arguments to routine
    minor: Bad value

显然我试图用错误的维度写数据,但我不知道如何纠正。我的目标是创建一个20x3的矩阵,并将第二行设置为{10, 20, 30}

 0  0  0
10 20 30
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0
 0  0  0

你能帮助我理解这个问题吗?我下面有一个有问题的代码!

谢谢!

#include "hdf5.h"

#define FILE "dset.h5"
#define DSET "/dset"

int main() {

  hid_t        file_id, dataset_id, dataspace_id, filespace, memspace;
  hsize_t      dims[2], offset[2], count[2];
  herr_t       status;

  unsigned int dset_data[3] = { 10, 20, 30 };

  /* Create a new file using default properties. */
  file_id = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

  /* Create the data space for the dataset. */
  dims[0] = 20; /* ROWS */
  dims[1] = 3;    /* COLS */
  dataspace_id = H5Screate_simple(2, dims, NULL);

  /* Create the dataset. */
  dataset_id = H5Dcreate2(file_id, DSET, H5T_STD_I32BE, dataspace_id,
                          H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

  /* Get the memory space */
  memspace = H5Dget_space (dataset_id);

  offset[0] = 1; /* ROWS */
  offset[1] = 0; /* COLS */

  count[0]  = 1; /* ROWS */
  count[1]  = 3; /* COLS */

  /* Select the slab */
  status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET,
                               offset, NULL, count, NULL);

  /* Write the dataset. */
  status = H5Dwrite(dataset_id, H5T_NATIVE_INT,
                    memspace, H5S_ALL, H5P_DEFAULT,
                    dset_data);

  /* End access to the dataset and release resources used by it. */
  status = H5Dclose(dataset_id);

  /* Terminate access to the data space. */
  status = H5Sclose(dataspace_id);

  /* Close the file. */
  status = H5Fclose(file_id);
} 
2个回答

3

您的数据在内存中是连续的(memspace),但在文件空间中是一个超平面(dataspace_id)。因此,您需要在dataset_id上进行选择,而不是memspace

并且您需要将memspace的大小调整为仅包含足够的空间以容纳您的行。在这里,我会创建一个简单的1D数据空间,其中包含3个元素。这样,超平面的大小(3个元素)和内存中的大小将匹配。


你好@Simon,我尝试为数据大小添加一个新变量newsize[1] = { 3 },在memspace = H5Dget_space (dataset_id);之后添加memspace的调整大小status = H5Dextend (memspace, newsize);,最后在数据集上进行块选择status = H5Sselect_hyperslab(dataset_id, H5S_SELECT_SET, offset, NULL, count, NULL);。但是我遇到了两个错误:H5Ddeprec.c line 315 in H5Dextend(): not a datasetH5Shyper.c line 6593 in H5Sselect_hyperslab(): not a data space。我在这里漏掉了什么...完整代码:https://gist.github.com/anonymous/ef0386340eefb4ef5b23 - newbiepp
不要试图“获取”内存空间,使用 H5Screate_simple 来创建它。 - Simon

0

顺便说一下,在调整原始源代码并保留原始的“memspace = H5Dget_space(dataset_id);”不变的情况下,我在Linux系统上使其正常工作。

#include <hdf5/serial/hdf5.h>

#define FILE "dset.h5"
#define DSET "/dset"

int main() {

  hid_t        file_id, dataset_id, dataspace_id, memspace;
  // hid_t filespace;
  hsize_t      dims[2], offset[2], count[2];
  herr_t       status;

  unsigned int dset_data[3] = { 10, 20, 30 };

  /* Create a new file using default properties. */
  file_id = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

  /* Create the data space for the dataset. */
  dims[0] = 20; /* ROWS */
  dims[1] = 3;    /* COLS */
  dataspace_id = H5Screate_simple(2, dims, NULL);

  /* Create the dataset. */
  dataset_id = H5Dcreate(file_id, DSET, H5T_STD_I32BE, dataspace_id,
                          H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

  /* Get the memory space */
  memspace = H5Dget_space (dataset_id);

  offset[0] = 1; /* ROWS */
  offset[1] = 0; /* COLS */

  count[0]  = 1; /* ROWS */
  count[1]  = 3; /* COLS */

  /* Select the slab */
  status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET,
                               offset, NULL, count, NULL);
  if(status < 0)
    return status;
    
  /* Write the dataset. */
  status = H5Dwrite(dataset_id, H5T_NATIVE_INT,
                    memspace, H5S_ALL, H5P_DEFAULT,
                    dset_data);
  if(status < 0)
    return status;

  /* End access to the dataset and release resources used by it. */
  status = H5Dclose(dataset_id);
  if(status < 0)
    return status;

  /* Terminate access to the data space. */
  status = H5Sclose(dataspace_id);
  if(status < 0)
    return status;

  /* Close the file. */
  status = H5Fclose(file_id);
  return status;
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接