C语言中HDF5输出多个时间切片

发现官网还是很好的学习资源, 关于C和C++版本的.

不断追加输出时间演化类型数据, 要注意几个点:

  • 创建的最大数据空间必须有一个维度足够大或者不设限制
        maxdims[0] = H5S_UNLIMITED;
        maxdims[1] = U.size();
        dimsf[0] = 1;
        dimsf[1] = U.size();
        dataspace = H5Screate_simple(RANK, dimsf, maxdims);
  • 将数据集的访问权限设置为开启chunking

Why chunking?
在这里插入图片描述

        /* Modify dataset creation properties, i.e. enable chunking  */
        property = H5Pcreate(H5P_DATASET_CREATE);
        hsize_t chunk_dims[2] = {1, U.size()};
        status = H5Pset_chunk(property, RANK, chunk_dims);

完整代码:

#include "hdf5.h"
#include <vector>
#include <string>
#include <iostream>
#include <cassert>

using namespace std;
using std::cout, std::endl;

int saveVec2HDF5_inside(int file, std::vector<double> &U, std::string varname, int mode)
{                       // HDF5 version = 1.8.21
    int RANK = 2;       /* RANK is Represents the dimension of the data space*/
    hsize_t num_slices; /* The number of time slices*/
    hid_t dataset;      /* dataset handles */
    hid_t datatype;     /* datatype handles*/
    hid_t dataspace;    /* dataspace handles*/
    hid_t memspace;     /* dataspace handles*/
    hid_t property;     /* property handles*/
    hsize_t dimsf[2];   /* dataset dimensions */
    hsize_t curr_dims[RANK];
    hsize_t maxdims[2];
    hsize_t start[2];
    hsize_t count[2];
    herr_t status;

    if (mode < 1)
    {
        if (H5Lexists(file, varname.c_str(), H5P_DEFAULT) > 0)
        {
            cout << "Dataset <" << varname
                 << "> already exists. Please use a different variable name" << endl;
            return 1;
        }
    }

    /*
     * Describe the size of the array and create the data space for fixed
     * size dataset. RANK is Represents the dimension of the data space,
     * i.e. the rank of the data space. In other words, RANK = the number
     * of elements in `dimsf` below.
     */
    if (mode < 1)
    {
        maxdims[0] = H5S_UNLIMITED;
        maxdims[1] = U.size();
        dimsf[0] = 1;
        dimsf[1] = U.size();
        dataspace = H5Screate_simple(RANK, dimsf, maxdims);

        /*
         * Define datatype for the data in the file.
         * We will store little endian numbers.
         */
        datatype = H5Tcopy(H5T_NATIVE_DOUBLE);
        status = H5Tset_order(datatype, H5T_ORDER_LE);
        assert(status == 0);

        /* Modify dataset creation properties, i.e. enable chunking  */
        property = H5Pcreate(H5P_DATASET_CREATE);
        hsize_t chunk_dims[2] = {1, U.size()};
        status = H5Pset_chunk(property, RANK, chunk_dims);

        /*
         * Create a new dataset within the file using defined dataspace and
         * datatype and dataset's chunk creation properties.
         */
        dataset = H5Dcreate2(file, varname.c_str(), datatype, dataspace,
                             H5P_DEFAULT, property, H5P_DEFAULT);

        /*
         * Write the data to the dataset using default transfer properties.
         */
        status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, U.data());
        assert(status == 0);
        /*
         * Close/release resources.
         */
        H5Pclose(property);
        H5Sclose(dataspace);
        H5Tclose(datatype);
        H5Dclose(dataset);
    }
    else
    {
        dataset = H5Dopen2(file, varname.c_str(), H5P_DEFAULT);
        assert(dataset > 0); /* if Var exists*/
        dataspace = H5Dget_space(dataset);
        H5Sget_simple_extent_dims(dataspace, curr_dims, NULL);
        assert(curr_dims[1] == U.size());
        // cout << "curr_dims[0,1] = " << curr_dims[0] << "," << curr_dims[1] << endl; /* debug*/
        num_slices = curr_dims[0];
        curr_dims[0] = num_slices + 1; // Extend the dataset by one time slice
        status = H5Dset_extent(dataset, curr_dims);
        assert(status == 0);
        dataspace = H5Dget_space(dataset);
        H5Sget_simple_extent_dims(dataspace, curr_dims, NULL);
        // cout << "curr_dims[0,1] = " << curr_dims[0] << "," << curr_dims[1] << endl; /* debug*/
        start[0] = num_slices;
        start[1] = 0;
        count[0] = 1;
        count[1] = U.size();
        status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, NULL, count, NULL);
        assert(status == 0);
        memspace = H5Screate_simple(2, count, NULL);
        status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, memspace, dataspace, H5P_DEFAULT, U.data());
        assert(status == 0);
        /*
         * Close/release resources.
         */
        H5Dclose(dataset);
        H5Sclose(dataspace);
        H5Sclose(memspace);
    }

    // H5Fclose(file); /* Should be closed outside this function*/

    return 0;
}

int main(void)
{
    hid_t file_id;
    std::vector<double> U(10, 0.0);
    int mode = 0;
    std::string dfname = "a.h5";
    if (mode == 0)
        file_id = H5Fcreate(dfname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    else
        file_id = H5Fopen(dfname.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);

    saveVec2HDF5_inside(file_id, U, std::string("U"), 0);
    // saveVec2HDF5_inside(file_id, U, std::string("U"), 0);
    saveVec2HDF5_inside(file_id, U, std::string("U"), 1);

    H5Fclose(file_id);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值