2018-12-05 08:03:56 +08:00
|
|
|
/* This is part of the netCDF package. Copyright 2018 University
|
2010-11-30 06:23:16 +08:00
|
|
|
Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
|
|
|
|
conditions of use.
|
|
|
|
|
|
|
|
This program does some HDF5 string stuff.
|
|
|
|
|
|
|
|
Here's a HDF5 sample programs:
|
|
|
|
http://hdf.ncsa.uiuc.edu/training/other-ex5/sample-programs/strings.c
|
|
|
|
*/
|
2011-03-21 23:45:17 +08:00
|
|
|
|
2011-11-14 12:20:19 +08:00
|
|
|
#include "h5_err_macros.h"
|
2010-11-30 06:23:16 +08:00
|
|
|
#include <hdf5.h>
|
|
|
|
|
|
|
|
#define FILE_NAME "tst_h_strings2.h5"
|
|
|
|
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
printf("\n*** Checking HDF5 string types even more.\n");
|
|
|
|
printf("*** Checking string dataset with unlimited dimension...");
|
|
|
|
{
|
|
|
|
#define VAR_NAME "Mark_Twain"
|
|
|
|
#define NDIMS 1
|
|
|
|
#define MY_CHUNK_CACHE_NELEMS 1009
|
|
|
|
#define MY_CHUNK_CACHE_SIZE 4194304
|
|
|
|
#define MY_CHUNK_CACHE_PREEMPTION .75
|
|
|
|
|
|
|
|
hid_t fapl_id, fcpl_id, fileid, grpid, spaceid, access_plistid;
|
|
|
|
hid_t typeid, datasetid, plistid, create_propid, dimscaleid;
|
|
|
|
hid_t file_spaceid, mem_spaceid;
|
|
|
|
hsize_t dims[1] = {0}, max_dims[1] = {H5S_UNLIMITED}, chunk_dims[1] = {1};
|
|
|
|
hsize_t xtend_size[NDIMS] = {2}, start[NDIMS] = {1}, count[NDIMS] = {1};
|
count argument in H5Sselect_hyperslab
Argument 'count' in NetCDF is not exactly the same as the 'count' in
H5Sselect_hyperslabs(space_id, op, start, stride, count, block).
When the argument 'stride' is NULL, NetCDF's 'count' should be used in
argument 'block', for example,
H5Sselect_hyperslabs(space_id, op, start, NULL, ones, count);
where 'one' is an array of all 1s. Although using NULL 'block' below
H5Sselect_hyperslabs(space_id, op, start, NULL, count, NULL);
has the same effect, HDF5 internally stores the space of a subarray as a
list of single elements, instead of a "block", which can affect the
performance.
2022-04-20 13:10:24 +08:00
|
|
|
hsize_t ones[NDIMS] = {1};
|
2010-11-30 06:23:16 +08:00
|
|
|
/* void *fillp;*/
|
|
|
|
char *data = "A man who carries a cat by the tail learns "
|
|
|
|
"something he can learn in no other way.";
|
|
|
|
/* char *empty = "";*/
|
|
|
|
|
|
|
|
/* Create file access and create property lists. */
|
|
|
|
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
|
|
|
|
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
|
|
|
|
* turns on HDF5 creation ordering in the file. */
|
|
|
|
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create the file, open root group. */
|
|
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
|
|
|
|
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
|
|
|
|
if (H5Pclose(fapl_id) < 0) ERR;
|
|
|
|
if (H5Pclose(fcpl_id) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create a dimension scale for unlimited dimension. */
|
|
|
|
if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
|
|
|
|
if (H5Pset_chunk(create_propid, NDIMS, chunk_dims) < 0) ERR;
|
|
|
|
if ((spaceid = H5Screate_simple(NDIMS, dims, max_dims)) < 0) ERR;
|
|
|
|
if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED|
|
|
|
|
H5P_CRT_ORDER_INDEXED) < 0) ERR;
|
|
|
|
if ((dimscaleid = H5Dcreate1(grpid, "unlimited_dim", H5T_IEEE_F32BE,
|
|
|
|
spaceid, create_propid)) < 0) ERR;
|
|
|
|
if (H5Sclose(spaceid) < 0) ERR;
|
|
|
|
if (H5Pclose(create_propid) < 0) ERR;
|
|
|
|
if (H5Dclose(dimscaleid) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create string type. */
|
|
|
|
if ((typeid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
|
|
if (H5Tset_size(typeid, H5T_VARIABLE) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create a space for our dataset. 0 data but unlimited dimension. */
|
|
|
|
if ((spaceid = H5Screate_simple(NDIMS, dims, max_dims)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Set up chunking, creation order, and cache. */
|
|
|
|
if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
|
|
|
|
if (H5Pset_chunk(plistid, NDIMS, chunk_dims) < 0) ERR;
|
|
|
|
if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
|
|
|
|
H5P_CRT_ORDER_INDEXED) < 0) ERR;
|
|
|
|
/* if (H5Pset_fill_value(plistid, typeid, &empty) < 0) ERR;*/
|
|
|
|
if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0) ERR;
|
|
|
|
if (H5Pset_chunk_cache(access_plistid, MY_CHUNK_CACHE_NELEMS,
|
|
|
|
MY_CHUNK_CACHE_SIZE, MY_CHUNK_CACHE_PREEMPTION) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create the dataset. It has zero records. */
|
|
|
|
if ((datasetid = H5Dcreate2(grpid, VAR_NAME, typeid, spaceid,
|
|
|
|
H5P_DEFAULT, plistid, access_plistid)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Now extend the dataset. */
|
|
|
|
if (H5Dextend(datasetid, xtend_size) < 0) ERR;
|
|
|
|
|
|
|
|
/* Select space in file to write a record. */
|
|
|
|
if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;
|
|
|
|
if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
|
count argument in H5Sselect_hyperslab
Argument 'count' in NetCDF is not exactly the same as the 'count' in
H5Sselect_hyperslabs(space_id, op, start, stride, count, block).
When the argument 'stride' is NULL, NetCDF's 'count' should be used in
argument 'block', for example,
H5Sselect_hyperslabs(space_id, op, start, NULL, ones, count);
where 'one' is an array of all 1s. Although using NULL 'block' below
H5Sselect_hyperslabs(space_id, op, start, NULL, count, NULL);
has the same effect, HDF5 internally stores the space of a subarray as a
list of single elements, instead of a "block", which can affect the
performance.
2022-04-20 13:10:24 +08:00
|
|
|
start, NULL, ones, count) < 0) ERR;
|
2010-11-30 06:23:16 +08:00
|
|
|
|
|
|
|
/* Select space in memory to read from. */
|
|
|
|
if ((mem_spaceid = H5Screate_simple(NDIMS, count, NULL)) < 0) ERR;
|
|
|
|
|
|
|
|
/*if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0) ERR;*/
|
|
|
|
|
|
|
|
/* Write the data. */
|
|
|
|
if (H5Dwrite(datasetid, typeid, mem_spaceid, file_spaceid,
|
|
|
|
H5P_DEFAULT, &data) < 0) ERR;
|
|
|
|
|
|
|
|
/* Close up. */
|
|
|
|
if (H5Sclose(file_spaceid) < 0) ERR;
|
|
|
|
if (H5Sclose(mem_spaceid) < 0) ERR;
|
|
|
|
if (H5Dclose(datasetid) < 0) ERR;
|
|
|
|
if (H5Pclose(access_plistid) < 0) ERR;
|
|
|
|
if (H5Pclose(plistid) < 0) ERR;
|
|
|
|
if (H5Tclose(typeid) < 0) ERR;
|
|
|
|
if (H5Sclose(spaceid) < 0) ERR;
|
|
|
|
if (H5Gclose(grpid) < 0) ERR;
|
|
|
|
if (H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
|
|
printf("*** Checking string dataset with unlimited dimension...");
|
|
|
|
{
|
|
|
|
#define VAR_NAME "Mark_Twain"
|
|
|
|
#define NDIMS 1
|
|
|
|
#define MY_CHUNK_CACHE_NELEMS 1009
|
|
|
|
#define MY_CHUNK_CACHE_SIZE 4194304
|
|
|
|
#define MY_CHUNK_CACHE_PREEMPTION .75
|
|
|
|
|
|
|
|
hid_t fapl_id, fcpl_id, fileid, grpid, spaceid, access_plistid;
|
|
|
|
hid_t typeid, datasetid, plistid;
|
|
|
|
hid_t file_spaceid, mem_spaceid;
|
|
|
|
hsize_t dims[1] = {2}, chunk_dims[1] = {1};
|
count argument in H5Sselect_hyperslab
Argument 'count' in NetCDF is not exactly the same as the 'count' in
H5Sselect_hyperslabs(space_id, op, start, stride, count, block).
When the argument 'stride' is NULL, NetCDF's 'count' should be used in
argument 'block', for example,
H5Sselect_hyperslabs(space_id, op, start, NULL, ones, count);
where 'one' is an array of all 1s. Although using NULL 'block' below
H5Sselect_hyperslabs(space_id, op, start, NULL, count, NULL);
has the same effect, HDF5 internally stores the space of a subarray as a
list of single elements, instead of a "block", which can affect the
performance.
2022-04-20 13:10:24 +08:00
|
|
|
hsize_t start[NDIMS] = {1}, count[NDIMS] = {1}, ones[NDIMS] = {1};
|
2010-11-30 06:23:16 +08:00
|
|
|
/* void *fillp;*/
|
|
|
|
char *data = "A man who carries a cat by the tail learns "
|
|
|
|
"something he can learn in no other way.";
|
|
|
|
/* Man - a creature made at the end of the week's work when God was tired.
|
|
|
|
There are basically two types of people. People who accomplish things, and people who claim to have accomplished things. The first group is less crowded.
|
|
|
|
To be good is noble; but to show others how to be good is nobler and no trouble. */
|
|
|
|
/* char *empty = "";*/
|
|
|
|
|
|
|
|
/* Create file access and create property lists. */
|
|
|
|
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
|
|
|
|
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
|
|
|
|
* turns on HDF5 creation ordering in the file. */
|
|
|
|
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
|
|
|
|
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create the file, open root group. */
|
|
|
|
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
|
|
|
|
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
|
|
|
|
if (H5Pclose(fapl_id) < 0) ERR;
|
|
|
|
if (H5Pclose(fcpl_id) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create string type. */
|
|
|
|
if ((typeid = H5Tcopy(H5T_C_S1)) < 0) ERR;
|
|
|
|
if (H5Tset_size(typeid, H5T_VARIABLE) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create a space for our dataset. */
|
|
|
|
if ((spaceid = H5Screate_simple(NDIMS, dims, dims)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Set up chunking, creation order, and cache. */
|
|
|
|
if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
|
|
|
|
if (H5Pset_chunk(plistid, NDIMS, chunk_dims) < 0) ERR;
|
|
|
|
if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
|
|
|
|
H5P_CRT_ORDER_INDEXED) < 0) ERR;
|
|
|
|
/* if (H5Pset_fill_value(plistid, typeid, &empty) < 0) ERR;*/
|
|
|
|
if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0) ERR;
|
|
|
|
if (H5Pset_chunk_cache(access_plistid, MY_CHUNK_CACHE_NELEMS,
|
|
|
|
MY_CHUNK_CACHE_SIZE, MY_CHUNK_CACHE_PREEMPTION) < 0) ERR;
|
|
|
|
|
|
|
|
/* Create the dataset. It has zero records. */
|
|
|
|
if ((datasetid = H5Dcreate2(grpid, VAR_NAME, typeid, spaceid,
|
|
|
|
H5P_DEFAULT, plistid, access_plistid)) < 0) ERR;
|
|
|
|
|
|
|
|
/* Now extend the dataset. */
|
|
|
|
/*if (H5Dextend(datasetid, xtend_size) < 0) ERR;*/
|
|
|
|
|
|
|
|
/* Select space in file to write a record. */
|
|
|
|
if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;
|
|
|
|
if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
|
count argument in H5Sselect_hyperslab
Argument 'count' in NetCDF is not exactly the same as the 'count' in
H5Sselect_hyperslabs(space_id, op, start, stride, count, block).
When the argument 'stride' is NULL, NetCDF's 'count' should be used in
argument 'block', for example,
H5Sselect_hyperslabs(space_id, op, start, NULL, ones, count);
where 'one' is an array of all 1s. Although using NULL 'block' below
H5Sselect_hyperslabs(space_id, op, start, NULL, count, NULL);
has the same effect, HDF5 internally stores the space of a subarray as a
list of single elements, instead of a "block", which can affect the
performance.
2022-04-20 13:10:24 +08:00
|
|
|
start, NULL, ones, count) < 0) ERR;
|
2010-11-30 06:23:16 +08:00
|
|
|
|
|
|
|
/* Select space in memory to read from. */
|
|
|
|
if ((mem_spaceid = H5Screate_simple(NDIMS, count, NULL)) < 0)
|
|
|
|
|
|
|
|
/*if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0) ERR;*/
|
|
|
|
|
|
|
|
/* Write the data. */
|
|
|
|
if (H5Dwrite(datasetid, typeid, mem_spaceid, file_spaceid,
|
|
|
|
H5P_DEFAULT, &data) < 0)
|
|
|
|
|
|
|
|
/* Close up. */
|
|
|
|
if (H5Dclose(datasetid) < 0) ERR;
|
|
|
|
if (H5Pclose(access_plistid) < 0) ERR;
|
|
|
|
if (H5Pclose(plistid) < 0) ERR;
|
|
|
|
if (H5Tclose(typeid) < 0) ERR;
|
|
|
|
if (H5Sclose(spaceid) < 0) ERR;
|
|
|
|
if (H5Gclose(grpid) < 0) ERR;
|
|
|
|
if (H5Fclose(fileid) < 0) ERR;
|
|
|
|
}
|
|
|
|
SUMMARIZE_ERR;
|
|
|
|
FINAL_RESULTS;
|
|
|
|
}
|