2017-01-27 03:34:12 +08:00
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
* Copyright by The HDF Group. *
|
|
|
|
* All rights reserved. *
|
|
|
|
* *
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
2017-04-18 03:32:16 +08:00
|
|
|
* the COPYING file, which can be found at the root of the source code *
|
|
|
|
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
|
|
|
* If you do not have access to either file, you may request a copy from *
|
|
|
|
* help@hdfgroup.org. *
|
2017-01-27 03:34:12 +08:00
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
|
|
#include "h5test.h"
|
|
|
|
|
|
|
|
/* This test uses many POSIX things that are not available on
|
|
|
|
* Windows. We're using a check for fork(2) here as a proxy for
|
|
|
|
* all POSIX/Unix/Linux things until this test can be made
|
|
|
|
* more platform-independent.
|
|
|
|
*/
|
|
|
|
#ifdef H5_HAVE_FORK
|
|
|
|
|
|
|
|
#include "use.h"
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Print a common/shared usage message.
|
|
|
|
* Receives program name to show default test file name (<program_name>.h5).
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
2017-01-27 03:34:12 +08:00
|
|
|
void
|
|
|
|
usage(const char *prog)
|
|
|
|
{
|
|
|
|
HDfprintf(stderr, "usage: %s [OPTIONS]\n", prog);
|
|
|
|
HDfprintf(stderr, " OPTIONS\n");
|
|
|
|
HDfprintf(stderr, " -h, --help Print a usage message and exit\n");
|
|
|
|
HDfprintf(stderr, " -f FN Test file name [default: %s.h5]\n", prog);
|
2020-09-30 22:27:10 +08:00
|
|
|
HDfprintf(stderr,
|
|
|
|
" -i N, --iteration=N Number of iterations to repeat the whole thing. [default: 1]\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
HDfprintf(stderr, " -l w|r launch writer or reader only. [default: launch both]\n");
|
|
|
|
HDfprintf(stderr, " -n N, --nplanes=N Number of planes to write/read. [default: 1000]\n");
|
|
|
|
HDfprintf(stderr, " -s N, --swmr=N Use SWMR mode (0: no, non-0: yes) default is yes\n");
|
|
|
|
HDfprintf(stderr, " -z N, --chunksize=N Chunk size [default: %d]\n", Chunksize_DFT);
|
|
|
|
HDfprintf(stderr, " -y N, --chunkplanes=N Number of planes per chunk [default: 1]\n");
|
|
|
|
HDfprintf(stderr, "\n");
|
|
|
|
} /* end usage() */
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Setup Use Case parameters by parsing command line options.
|
|
|
|
* Includes default values for unspecified options.
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
2017-01-27 03:34:12 +08:00
|
|
|
int
|
2020-09-30 22:27:10 +08:00
|
|
|
parse_option(int argc, char *const argv[], options_t *opts)
|
2017-01-27 03:34:12 +08:00
|
|
|
{
|
2020-09-30 22:27:10 +08:00
|
|
|
int ret_value = 0;
|
2017-01-27 03:34:12 +08:00
|
|
|
int c;
|
2020-09-30 22:27:10 +08:00
|
|
|
int use_swmr; /* Need an int to detect errors */
|
2017-05-25 18:45:53 +08:00
|
|
|
|
2017-01-27 03:34:12 +08:00
|
|
|
/* command line options: See function usage for a description */
|
|
|
|
const char *nagg_options = "f:hi:l:n:s:y:z:";
|
|
|
|
|
|
|
|
/* suppress getopt from printing error */
|
|
|
|
opterr = 0;
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
while (1) {
|
|
|
|
c = getopt(argc, argv, nagg_options);
|
|
|
|
if (-1 == c)
|
|
|
|
break;
|
|
|
|
switch (c) {
|
2020-09-30 22:27:10 +08:00
|
|
|
case 'h':
|
2020-03-14 06:13:17 +08:00
|
|
|
usage(opts->progname);
|
2020-10-24 08:13:05 +08:00
|
|
|
HDexit(EXIT_SUCCESS);
|
2020-03-14 06:13:17 +08:00
|
|
|
break;
|
2020-09-30 22:27:10 +08:00
|
|
|
case 'f': /* usecase data file name */
|
|
|
|
opts->filename = HDstrdup(optarg);
|
2020-03-14 06:13:17 +08:00
|
|
|
break;
|
2020-09-30 22:27:10 +08:00
|
|
|
case 'i': /* iterations */
|
|
|
|
if ((opts->iterations = HDatoi(optarg)) <= 0) {
|
|
|
|
HDfprintf(stderr, "bad iterations number %s, must be a positive integer\n", optarg);
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
break;
|
2020-09-30 22:27:10 +08:00
|
|
|
case 'l': /* launch reader or writer only */
|
|
|
|
switch (*optarg) {
|
|
|
|
case 'r': /* reader only */
|
|
|
|
opts->launch = UC_READER;
|
|
|
|
break;
|
|
|
|
case 'w': /* writer only */
|
|
|
|
opts->launch = UC_WRITER;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
HDfprintf(stderr, "launch value(%c) should be w or r only.\n", *optarg);
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
break;
|
|
|
|
} /* end switch (reader/writer-only mode toggle) */
|
|
|
|
break;
|
|
|
|
case 'n': /* number of planes to write/read */
|
|
|
|
if ((opts->nplanes = HDstrtoul(optarg, NULL, 0)) <= 0) {
|
|
|
|
HDfprintf(stderr, "bad number of planes %s, must be a positive integer\n", optarg);
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's': /* use swmr file open mode */
|
|
|
|
use_swmr = HDatoi(optarg);
|
|
|
|
if (use_swmr != 0 && use_swmr != 1) {
|
|
|
|
HDfprintf(stderr, "swmr value should be 0(no) or 1(yes)\n");
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
|
|
|
opts->use_swmr = (hbool_t)use_swmr;
|
|
|
|
break;
|
|
|
|
case 'y': /* Number of planes per chunk */
|
|
|
|
if ((opts->chunkplanes = HDstrtoul(optarg, NULL, 0)) <= 0) {
|
|
|
|
HDfprintf(stderr, "bad number of planes per chunk %s, must be a positive integer\n",
|
|
|
|
optarg);
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'z': /* size of chunk=(z,z) */
|
|
|
|
if ((opts->chunksize = HDstrtoull(optarg, NULL, 0)) <= 0) {
|
|
|
|
HDfprintf(stderr, "bad chunksize %s, must be a positive integer\n", optarg);
|
|
|
|
usage(opts->progname);
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
HDfprintf(stderr, "getopt returned '%c'.\n", c);
|
2020-03-14 06:13:17 +08:00
|
|
|
Hgoto_error(-1);
|
2020-09-30 22:27:10 +08:00
|
|
|
default:
|
|
|
|
HDfprintf(stderr, "getopt returned unexpected value.\n");
|
|
|
|
HDfprintf(stderr, "Unexpected value is %d\n", c);
|
2020-03-14 06:13:17 +08:00
|
|
|
Hgoto_error(-1);
|
|
|
|
} /* end switch (argument symbol) */
|
2020-09-30 22:27:10 +08:00
|
|
|
} /* end while (there are still arguments) */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* set test file name if not given */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (!opts->filename) {
|
|
|
|
/* default data file name is <progname>.h5 */
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((opts->filename = (char *)HDmalloc(HDstrlen(opts->progname) + 4)) == NULL) {
|
2020-03-14 06:13:17 +08:00
|
|
|
HDfprintf(stderr, "malloc: failed\n");
|
|
|
|
Hgoto_error(-1);
|
|
|
|
}
|
|
|
|
HDstrcpy(opts->filename, opts->progname);
|
|
|
|
HDstrcat(opts->filename, ".h5");
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
2020-09-30 22:27:10 +08:00
|
|
|
return (ret_value);
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end parse_option() */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Show parameters used for this use case.
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void
|
2020-09-30 22:27:10 +08:00
|
|
|
show_parameters(options_t *opts)
|
2020-03-14 06:13:17 +08:00
|
|
|
{
|
2019-08-16 05:46:00 +08:00
|
|
|
HDprintf("===Parameters used:===\n");
|
2020-04-21 07:12:00 +08:00
|
|
|
HDprintf("chunk dims=(%llu, %llu, %llu)\n", (unsigned long long)opts->chunkdims[0],
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)opts->chunkdims[1], (unsigned long long)opts->chunkdims[2]);
|
2020-04-21 07:12:00 +08:00
|
|
|
HDprintf("dataset max dims=(%llu, %llu, %llu)\n", (unsigned long long)opts->max_dims[0],
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)opts->max_dims[1], (unsigned long long)opts->max_dims[2]);
|
2020-03-14 06:13:17 +08:00
|
|
|
HDprintf("number of planes to write=%llu\n", (unsigned long long)opts->nplanes);
|
|
|
|
HDprintf("using SWMR mode=%s\n", opts->use_swmr ? "yes(1)" : "no(0)");
|
|
|
|
HDprintf("data filename=%s\n", opts->filename);
|
2019-08-16 05:46:00 +08:00
|
|
|
HDprintf("launch part=");
|
2020-09-30 22:27:10 +08:00
|
|
|
switch (opts->launch) {
|
2020-03-14 06:13:17 +08:00
|
|
|
case UC_READWRITE:
|
|
|
|
HDprintf("Reader/Writer\n");
|
|
|
|
break;
|
|
|
|
case UC_WRITER:
|
|
|
|
HDprintf("Writer\n");
|
|
|
|
break;
|
|
|
|
case UC_READER:
|
|
|
|
HDprintf("Reader\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* should not happen */
|
|
|
|
HDprintf("Illegal part(%d)\n", opts->launch);
|
2020-09-30 22:27:10 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
HDprintf("number of iterations=%d (not used yet)\n", opts->iterations);
|
2019-08-16 05:46:00 +08:00
|
|
|
HDprintf("===Parameters shown===\n");
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end show_parameters() */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Create the skeleton use case file for testing.
|
2017-01-27 03:34:12 +08:00
|
|
|
* It has one 3d dataset using chunked storage.
|
|
|
|
* The dataset is (unlimited, chunksize, chunksize).
|
|
|
|
* Dataset type is 2 bytes integer.
|
|
|
|
* It starts out "empty", i.e., first dimension is 0.
|
|
|
|
*
|
|
|
|
* Return: 0 succeed; -1 fail.
|
2020-03-14 06:13:17 +08:00
|
|
|
* ----------------------------------------------------------------------------
|
2017-01-27 03:34:12 +08:00
|
|
|
*/
|
2020-03-14 06:13:17 +08:00
|
|
|
int
|
2020-09-30 22:27:10 +08:00
|
|
|
create_uc_file(options_t *opts)
|
2017-01-27 03:34:12 +08:00
|
|
|
{
|
2020-09-30 22:27:10 +08:00
|
|
|
hsize_t dims[3]; /* Dataset starting dimensions */
|
|
|
|
hid_t fid; /* File ID for new HDF5 file */
|
|
|
|
hid_t dcpl; /* Dataset creation property list */
|
|
|
|
hid_t sid; /* Dataspace ID */
|
|
|
|
hid_t dsid; /* Dataset ID */
|
2017-01-27 03:34:12 +08:00
|
|
|
H5D_chunk_index_t idx_type; /* Chunk index type */
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((fid = H5Fcreate(opts->filename, H5F_ACC_TRUNC, H5P_DEFAULT, opts->fapl_id)) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Set up dimension sizes */
|
|
|
|
dims[0] = 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
dims[1] = dims[2] = opts->max_dims[1];
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Create dataspace for creating datasets */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((sid = H5Screate_simple(3, dims, opts->max_dims)) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Create dataset creation property list */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Pset_chunk(dcpl, 3, opts->chunkdims) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* create dataset of progname */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((dsid = H5Dcreate2(fid, opts->progname, UC_DATATYPE, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Check that the chunk index type is not version 1 B-tree.
|
|
|
|
* Version 1 B-trees are not supported under SWMR.
|
|
|
|
*/
|
2020-04-07 23:16:48 +08:00
|
|
|
if (H5Dget_chunk_index_type(dsid, &idx_type) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (idx_type == H5D_CHUNK_IDX_BTREE) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "ERROR: Chunk index is version 1 B-tree: aborting.\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close everything */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Dclose(dsid) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Pclose(dcpl) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sclose(sid) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Fclose(fid) < 0)
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end create_uc_file() */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Append planes, each of (1,2*chunksize,2*chunksize) to the dataset.
|
2017-01-27 03:34:12 +08:00
|
|
|
* In other words, 4 chunks are appended to the dataset at a time.
|
|
|
|
* Fill each plan with the plane number and then write it at the nth plane.
|
|
|
|
* Increase the plane number and repeat till the end of dataset, when it
|
|
|
|
* reaches chunksize long. End product is a (2*chunksize)^3 cube.
|
|
|
|
*
|
|
|
|
* Return: 0 succeed; -1 fail.
|
2020-03-14 06:13:17 +08:00
|
|
|
* ----------------------------------------------------------------------------
|
2017-01-27 03:34:12 +08:00
|
|
|
*/
|
2020-03-14 06:13:17 +08:00
|
|
|
int
|
2020-09-30 22:27:10 +08:00
|
|
|
write_uc_file(hbool_t tosend, hid_t file_id, options_t *opts)
|
2017-01-27 03:34:12 +08:00
|
|
|
{
|
2020-09-30 22:27:10 +08:00
|
|
|
hid_t dsid; /* dataset ID */
|
|
|
|
hid_t dcpl; /* Dataset creation property list */
|
|
|
|
UC_CTYPE *buffer, *bufptr; /* data buffer */
|
|
|
|
hsize_t cz = opts->chunksize; /* Chunk size */
|
|
|
|
hid_t f_sid; /* dataset file space id */
|
|
|
|
hid_t m_sid; /* memory space id */
|
|
|
|
int rank; /* rank */
|
|
|
|
hsize_t chunk_dims[3]; /* Chunk dimensions */
|
|
|
|
hsize_t dims[3]; /* Dataspace dimensions */
|
|
|
|
hsize_t memdims[3]; /* Memory space dimensions */
|
|
|
|
hsize_t start[3] = {0, 0, 0}, count[3]; /* Hyperslab selection values */
|
2020-03-14 06:13:17 +08:00
|
|
|
hsize_t i, j, k;
|
|
|
|
|
|
|
|
if (TRUE == tosend) {
|
2017-01-27 03:34:12 +08:00
|
|
|
/* Send a message that H5Fopen is complete--releasing the file lock */
|
|
|
|
h5_send_message(WRITER_MESSAGE, NULL, NULL);
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Open the dataset of the program name */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((dsid = H5Dopen2(file_id, opts->progname, H5P_DEFAULT)) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Dopen2 failed\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find chunksize used */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((dcpl = H5Dget_create_plist(dsid)) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Dget_create_plist failed\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5D_CHUNKED != H5Pget_layout(dcpl)) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "storage layout is not chunked\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((rank = H5Pget_chunk(dcpl, 3, chunk_dims)) != 3) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "storage rank is not 3\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* verify chunk_dims against set paramenters */
|
2020-09-30 22:27:10 +08:00
|
|
|
if (chunk_dims[0] != opts->chunkdims[0] || chunk_dims[1] != cz || chunk_dims[2] != cz) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "chunk size is not as expected. Got dims=(%llu,%llu,%llu)\n",
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)chunk_dims[0], (unsigned long long)chunk_dims[1],
|
|
|
|
(unsigned long long)chunk_dims[2]);
|
2019-08-16 05:46:00 +08:00
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate space for data buffer 1 X dims[1] X dims[2] of UC_CTYPE */
|
2020-09-30 22:27:10 +08:00
|
|
|
memdims[0] = 1;
|
2020-03-14 06:13:17 +08:00
|
|
|
memdims[1] = opts->dims[1];
|
|
|
|
memdims[2] = opts->dims[2];
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((buffer = (UC_CTYPE *)HDmalloc((size_t)memdims[1] * (size_t)memdims[2] * sizeof(UC_CTYPE))) == NULL) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "malloc: failed\n");
|
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get dataset rank and dimension.
|
|
|
|
*/
|
2020-09-30 22:27:10 +08:00
|
|
|
f_sid = H5Dget_space(dsid); /* Get filespace handle first. */
|
2017-01-27 03:34:12 +08:00
|
|
|
rank = H5Sget_simple_extent_ndims(f_sid);
|
2020-03-14 06:13:17 +08:00
|
|
|
if (rank != UC_RANK) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "rank(%d) of dataset does not match\n", rank);
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sget_simple_extent_dims(f_sid, dims, NULL) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Sget_simple_extent_dims got error\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-09-30 22:27:10 +08:00
|
|
|
HDprintf("dataset rank %d, dimensions %llu x %llu x %llu\n", rank, (unsigned long long)(dims[0]),
|
|
|
|
(unsigned long long)(dims[1]), (unsigned long long)(dims[2]));
|
2017-01-27 03:34:12 +08:00
|
|
|
/* verify that file space dims are as expected and are consistent with memory space dims */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (dims[0] != 0 || dims[1] != memdims[1] || dims[2] != memdims[2]) {
|
2020-09-30 22:27:10 +08:00
|
|
|
HDfprintf(stderr, "dataset is not empty. Got dims=(%llu,%llu,%llu)\n", (unsigned long long)dims[0],
|
|
|
|
(unsigned long long)dims[1], (unsigned long long)dims[2]);
|
2019-08-16 05:46:00 +08:00
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2019-08-16 05:46:00 +08:00
|
|
|
|
2017-01-27 03:34:12 +08:00
|
|
|
/* setup mem-space for buffer */
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((m_sid = H5Screate_simple(rank, memdims, NULL)) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Screate_simple for memory failed\n");
|
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* write planes */
|
2020-09-30 22:27:10 +08:00
|
|
|
count[0] = 1;
|
|
|
|
count[1] = dims[1];
|
|
|
|
count[2] = dims[2];
|
|
|
|
for (i = 0; i < opts->nplanes; i++) {
|
2020-01-27 23:01:32 +08:00
|
|
|
/* fill buffer with value i+1 */
|
|
|
|
bufptr = buffer;
|
2020-09-30 22:27:10 +08:00
|
|
|
for (j = 0; j < dims[1]; j++) {
|
|
|
|
for (k = 0; k < dims[2]; k++) {
|
2020-01-27 23:01:32 +08:00
|
|
|
*bufptr++ = (UC_CTYPE)i;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Cork the dataset's metadata in the cache, if SWMR is enabled */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (opts->use_swmr) {
|
|
|
|
if (H5Odisable_mdc_flushes(dsid) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Odisable_mdc_flushes failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2020-01-27 23:01:32 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-01-27 23:01:32 +08:00
|
|
|
/* extend the dataset by one for new plane */
|
2020-09-30 22:27:10 +08:00
|
|
|
dims[0] = i + 1;
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Dset_extent(dsid, dims) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Dset_extent failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-01-27 23:01:32 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Get the dataset's dataspace */
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((f_sid = H5Dget_space(dsid)) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Dset_extent failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-01-27 23:01:32 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-09-30 22:27:10 +08:00
|
|
|
start[0] = i;
|
2017-01-27 03:34:12 +08:00
|
|
|
/* Choose the next plane to write */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sselect_hyperslab(f_sid, H5S_SELECT_SET, start, NULL, count, NULL) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "Failed H5Sselect_hyperslab\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-01-27 23:01:32 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Write plane to the dataset */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Dwrite(dsid, UC_DATATYPE, m_sid, f_sid, H5P_DEFAULT, buffer) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "Failed H5Dwrite\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
2020-01-27 23:01:32 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Uncork the dataset's metadata from the cache, if SWMR is enabled */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (opts->use_swmr) {
|
|
|
|
if (H5Oenable_mdc_flushes(dsid) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "H5Oenable_mdc_flushes failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-01-27 23:01:32 +08:00
|
|
|
/* flush file to make the just written plane available. */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Dflush(dsid) < 0) {
|
2020-01-27 23:01:32 +08:00
|
|
|
HDfprintf(stderr, "Failed to H5Fflush file\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end for each plane to write */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Done writing. Free/Close all resources including data file */
|
|
|
|
HDfree(buffer);
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Dclose(dsid) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "Failed to close datasete\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sclose(m_sid) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "Failed to close memory space\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sclose(f_sid) < 0) {
|
2019-08-16 05:46:00 +08:00
|
|
|
HDfprintf(stderr, "Failed to close file space\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end write_uc_file() */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Read planes from the dataset.
|
2017-01-27 03:34:12 +08:00
|
|
|
* It expects the dataset is being changed (growing).
|
|
|
|
* It checks the unlimited dimension (1st one). When it increases,
|
|
|
|
* it will read in the new planes, one by one, and verify the data correctness.
|
|
|
|
* (The nth plan should contain all "n".)
|
|
|
|
* When the unlimited dimension grows to the chunksize (it becomes a cube),
|
|
|
|
* that is the expected end of data, the reader exits.
|
|
|
|
*
|
|
|
|
* Return: 0 succeed; -1 fail.
|
2020-03-14 06:13:17 +08:00
|
|
|
* ----------------------------------------------------------------------------
|
2017-01-27 03:34:12 +08:00
|
|
|
*/
|
2020-03-14 06:13:17 +08:00
|
|
|
int
|
2020-09-30 22:27:10 +08:00
|
|
|
read_uc_file(hbool_t towait, options_t *opts)
|
2017-01-27 03:34:12 +08:00
|
|
|
{
|
2020-09-30 22:27:10 +08:00
|
|
|
hid_t fid; /* File ID for new HDF5 file */
|
|
|
|
hid_t dsid; /* dataset ID */
|
2020-12-04 01:16:30 +08:00
|
|
|
UC_CTYPE *buffer = NULL, *bufptr = NULL; /* read data buffer */
|
2020-09-30 22:27:10 +08:00
|
|
|
hid_t f_sid; /* dataset file space id */
|
|
|
|
hid_t m_sid; /* memory space id */
|
|
|
|
int rank; /* rank */
|
|
|
|
hsize_t dims[3]; /* Dataspace dimensions */
|
|
|
|
hsize_t memdims[3]; /* Memory space dimensions */
|
|
|
|
hsize_t nplane = 0, nplanes_seen = 0; /* nth plane, last nth plane */
|
|
|
|
hsize_t start[3] = {0, 0, 0}, count[3]; /* Hyperslab selection values */
|
2020-03-14 06:13:17 +08:00
|
|
|
hsize_t j, k;
|
2020-09-30 22:27:10 +08:00
|
|
|
int nreadererr = 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
int nerrs;
|
|
|
|
int loops_waiting_for_plane;
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/* Before reading, wait for the message that H5Fopen is complete--file lock is released */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (towait && h5_wait_message(WRITER_MESSAGE) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "Cannot find writer message file...failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
HDfprintf(stderr, "Opening to read %s\n", opts->filename);
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((fid = H5Fopen(opts->filename, H5F_ACC_RDONLY | (opts->use_swmr ? H5F_ACC_SWMR_READ : 0),
|
|
|
|
opts->fapl_id)) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "H5Fopen failed\n");
|
2017-01-27 03:34:12 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((dsid = H5Dopen2(fid, opts->progname, H5P_DEFAULT)) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "H5Dopen2 failed\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* Allocate space for data buffer 1 X dims[1] X dims[2] of UC_CTYPE */
|
|
|
|
memdims[0] = 1;
|
|
|
|
memdims[1] = opts->dims[1];
|
|
|
|
memdims[2] = opts->dims[2];
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((buffer = (UC_CTYPE *)HDmalloc((size_t)memdims[1] * (size_t)memdims[2] * sizeof(UC_CTYPE))) == NULL) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "malloc: failed\n");
|
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get dataset rank and dimension.
|
|
|
|
* Verify dimension is as expected (unlimited,2*chunksize,2*chunksize).
|
|
|
|
*/
|
2020-09-30 22:27:10 +08:00
|
|
|
f_sid = H5Dget_space(dsid); /* Get filespace handle first. */
|
2017-01-27 03:34:12 +08:00
|
|
|
rank = H5Sget_simple_extent_ndims(f_sid);
|
2020-03-14 06:13:17 +08:00
|
|
|
if (rank != UC_RANK) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "rank(%d) of dataset does not match\n", rank);
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sget_simple_extent_dims(f_sid, dims, NULL) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "H5Sget_simple_extent_dims got error\n");
|
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2020-09-30 22:27:10 +08:00
|
|
|
HDprintf("dataset rank %d, dimensions %llu x %llu x %llu\n", rank, (unsigned long long)(dims[0]),
|
|
|
|
(unsigned long long)(dims[1]), (unsigned long long)(dims[2]));
|
2017-01-27 03:34:12 +08:00
|
|
|
/* verify that file space dims are as expected and are consistent with memory space dims */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (dims[1] != memdims[1] || dims[2] != memdims[2]) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "dataset dimension is not as expected. Got dims=(%llu,%llu,%llu)\n",
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)dims[0], (unsigned long long)dims[1], (unsigned long long)dims[2]);
|
|
|
|
HDfprintf(stderr, "But memdims=(%llu,%llu,%llu)\n", (unsigned long long)memdims[0],
|
|
|
|
(unsigned long long)memdims[1], (unsigned long long)memdims[2]);
|
2018-11-02 01:03:34 +08:00
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
}
|
2019-08-16 05:46:00 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* Setup mem-space for buffer */
|
2020-09-30 22:27:10 +08:00
|
|
|
if ((m_sid = H5Screate_simple(rank, memdims, NULL)) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "H5Screate_simple for memory failed\n");
|
|
|
|
return -1;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* Read 1 plane at a time whenever the dataset grows larger (along dim[0]) */
|
|
|
|
count[0] = 1;
|
|
|
|
count[1] = dims[1];
|
|
|
|
count[2] = dims[2];
|
2017-01-27 03:34:12 +08:00
|
|
|
/* quit when all nplanes have been read */
|
2020-09-30 22:27:10 +08:00
|
|
|
loops_waiting_for_plane = 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
while (nplanes_seen < opts->nplanes) {
|
|
|
|
/* print progress message according to if new planes are availalbe */
|
|
|
|
if (nplanes_seen < dims[0]) {
|
|
|
|
if (loops_waiting_for_plane) {
|
|
|
|
/* end the previous message */
|
|
|
|
HDprintf("\n");
|
2020-09-30 22:27:10 +08:00
|
|
|
loops_waiting_for_plane = 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
2020-04-21 07:12:00 +08:00
|
|
|
HDprintf("reading planes %llu to %llu\n", (unsigned long long)nplanes_seen,
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)dims[0]);
|
2019-08-16 05:46:00 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
else {
|
|
|
|
if (loops_waiting_for_plane) {
|
|
|
|
HDprintf(".");
|
2020-09-30 22:27:10 +08:00
|
|
|
if (loops_waiting_for_plane >= 30) {
|
2020-03-14 06:13:17 +08:00
|
|
|
HDfprintf(stderr, "waited too long for new plane, quit.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* print mesg only the first time; dots still no new plane */
|
|
|
|
HDprintf("waiting for new planes to read ");
|
|
|
|
}
|
|
|
|
loops_waiting_for_plane++;
|
|
|
|
/* pause for a second */
|
|
|
|
HDsleep(1);
|
2019-08-16 05:46:00 +08:00
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-09-30 22:27:10 +08:00
|
|
|
for (nplane = nplanes_seen; nplane < dims[0]; nplane++) {
|
2020-03-14 06:13:17 +08:00
|
|
|
/* read planes between last old nplanes and current extent */
|
|
|
|
/* Get the dataset's dataspace */
|
|
|
|
if ((f_sid = H5Dget_space(dsid)) < 0) {
|
|
|
|
HDfprintf(stderr, "H5Dget_space failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-09-30 22:27:10 +08:00
|
|
|
start[0] = nplane;
|
2020-03-14 06:13:17 +08:00
|
|
|
/* Choose the next plane to read */
|
|
|
|
if (H5Sselect_hyperslab(f_sid, H5S_SELECT_SET, start, NULL, count, NULL) < 0) {
|
|
|
|
HDfprintf(stderr, "H5Sselect_hyperslab failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
/* Read the plane from the dataset */
|
|
|
|
if (H5Dread(dsid, UC_DATATYPE, m_sid, f_sid, H5P_DEFAULT, buffer) < 0) {
|
|
|
|
HDfprintf(stderr, "H5Dread failed\n");
|
|
|
|
return -1;
|
2018-11-02 01:03:34 +08:00
|
|
|
}
|
2020-03-14 06:13:17 +08:00
|
|
|
|
|
|
|
/* compare read data with expected data value which is nplane */
|
|
|
|
bufptr = buffer;
|
2020-09-30 22:27:10 +08:00
|
|
|
nerrs = 0;
|
|
|
|
for (j = 0; j < dims[1]; j++) {
|
|
|
|
for (k = 0; k < dims[2]; k++) {
|
2020-03-14 06:13:17 +08:00
|
|
|
if ((hsize_t)*bufptr++ != nplane) {
|
|
|
|
if (++nerrs < ErrorReportMax) {
|
2020-09-30 22:27:10 +08:00
|
|
|
HDfprintf(stderr, "found error %llu plane(%llu,%llu), expected %llu, got %d\n",
|
|
|
|
(unsigned long long)nplane, (unsigned long long)j,
|
|
|
|
(unsigned long long)k, (unsigned long long)nplane, (int)*(bufptr - 1));
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end if should print error */
|
2020-09-30 22:27:10 +08:00
|
|
|
} /* end if value mismatch */
|
|
|
|
} /* end for plane second dimension */
|
|
|
|
} /* end for plane first dimension */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (nerrs) {
|
|
|
|
nreadererr++;
|
2020-04-21 07:12:00 +08:00
|
|
|
HDfprintf(stderr, "found %d unexpected values in plane %llu\n", nerrs,
|
2020-09-30 22:27:10 +08:00
|
|
|
(unsigned long long)nplane);
|
2020-03-14 06:13:17 +08:00
|
|
|
}
|
|
|
|
} /* end for each plane added since last read */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-09-30 22:27:10 +08:00
|
|
|
nplanes_seen = dims[0];
|
2020-03-14 06:13:17 +08:00
|
|
|
|
|
|
|
/* check if dataset has grown since last time (update dims) */
|
|
|
|
H5Drefresh(dsid);
|
2020-09-30 22:27:10 +08:00
|
|
|
f_sid = H5Dget_space(dsid); /* Get filespace handle first. */
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Sget_simple_extent_dims(f_sid, dims, NULL) < 0) {
|
|
|
|
HDfprintf(stderr, "H5Sget_simple_extent_dims got error\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} /* end while (expecting more planes to read) */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
2020-03-14 06:13:17 +08:00
|
|
|
if (H5Fclose(fid) < 0) {
|
2018-11-02 01:03:34 +08:00
|
|
|
HDfprintf(stderr, "H5Fclose failed\n");
|
2018-10-31 05:53:09 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-12-04 01:16:30 +08:00
|
|
|
HDfree(buffer);
|
|
|
|
|
2017-01-27 03:34:12 +08:00
|
|
|
if (nreadererr)
|
2018-11-02 01:03:34 +08:00
|
|
|
return -1;
|
2017-01-27 03:34:12 +08:00
|
|
|
else
|
2018-11-02 01:03:34 +08:00
|
|
|
return 0;
|
2020-03-14 06:13:17 +08:00
|
|
|
} /* end read_uc_file() */
|
2017-01-27 03:34:12 +08:00
|
|
|
|
|
|
|
#endif /* H5_HAVE_FORK */
|