From 6f56d06f6af371b8b8c58079d8200647df249ee2 Mon Sep 17 00:00:00 2001 From: vchoi-hdfgroup <55293060+vchoi-hdfgroup@users.noreply.github.com> Date: Tue, 10 Oct 2023 10:13:00 -0500 Subject: [PATCH] Add more tests for selection I/O. (#3528) --- src/H5Dscatgath.c | 2 +- test/cmpd_dset.c | 1216 ++++++++++++++++++++++++++++++++++++++++- test/select_io_dset.c | 243 ++++---- 3 files changed, 1338 insertions(+), 123 deletions(-) diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index f0a0b9de1cb..9b60d81b2b0 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -718,7 +718,7 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset /* Use "vp" field of union to twiddle away const. OK because if we're doing this it means the * user explicitly allowed us to modify this buffer via H5Pset_modify_write_buf(). */ tmp_buf = (uint8_t *)dset_info->buf.vp + dset_info->layout_io_info.contig_piece_info->buf_off + - (smine_start * dset_info->type_info.dst_type_size); + (smine_start * dset_info->type_info.src_type_size); } else { /* Do type conversion using intermediate buffer */ diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 3ead12f7d96..02dbde3759a 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -19,7 +19,7 @@ #include "h5test.h" -static const char *FILENAME[] = {"cmpd_dset", "src_subset", "dst_subset", NULL}; +static const char *FILENAME[] = {"cmpd_dset", "src_subset", "dst_subset", "select_cmpd_dset", NULL}; const char *DSET_NAME[] = {"contig_src_subset", "chunk_src_subset", "contig_dst_subset", "chunk_dst_subset", NULL}; @@ -78,6 +78,17 @@ typedef struct s6_t { unsigned int post; } s6_t; +typedef struct s7_t { + int32_t a; + int32_t d; +} s7_t; + +typedef struct s8_t { + int64_t a; + int64_t b; + int64_t c; +} s8_t; + /* Structures for testing the optimization for the Chicago company. */ typedef struct { int a, b, c[8], d, e; @@ -85,28 +96,1186 @@ typedef struct { double k, l, m, n; } stype1; -typedef struct { - int a, b, c[8], d, e; - float f, g, h[16], i, j; - double k, l, m, n; - long o, p, q; -} stype2; +typedef struct { + int a, b, c[8], d, e; + float f, g, h[16], i, j; + double k, l, m, n; + long o, p, q; +} stype2; + +typedef struct { + int a, b, c[8], d, e; +} stype3; + +typedef struct { + int a, b, c[8], d, e; + float f, g, h[16], i, j; + double k, l, m, n; + long o, p, q; + long long r, s, t; +} stype4; + +#define NX 100U +#define NY 2000U +#define PACK_NMEMBS 100 + +static void initialize_stype1(unsigned char *buf, size_t num); +static void initialize_stype2(unsigned char *buf, size_t num); +static void initialize_stype3(unsigned char *buf, size_t num); +static void initialize_stype4(unsigned char *buf, size_t num); +static hid_t create_stype1(void); +static hid_t create_stype2(void); +static hid_t create_stype3(void); +static hid_t create_stype4(void); +static int compare_data(void *src_data, void *dst_data, hbool_t src_subset); +static int compare_stype4_data(void *expect_buf, void *rbuf); +static int compare_s1_data(void *expect_buf, void *rbuf); +static int compare_s1_s3_data(void *expect_buf, void *rbuf); +static int compare_s7_data(void *expect_buf, void *rbuf); +static int compare_a_d_data(void *exp1_buf, void *exp2_buf, void *rbuf); +static int compare_a_b_c_data(void *exp1_buf, void *exp2_buf, void *rbuf); + +/*------------------------------------------------------------------------- + * Function: compare_stype4_data + * + * Purpose: Compare data (the common fields in stype4/stype2) read in rbuf with expected data + * in expect_buf. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_stype4_data(void *expect_buf, void *rbuf) +{ + int i; + + for (i = 0; i < (int)(NX * NY); i++) { + stype4 *s1_ptr; + stype4 *s2_ptr; + s1_ptr = ((stype4 *)expect_buf) + i; + s2_ptr = ((stype4 *)rbuf) + i; + + if (s1_ptr->a != s2_ptr->a || s1_ptr->b != s2_ptr->b || s1_ptr->c[0] != s2_ptr->c[0] || + s1_ptr->c[1] != s2_ptr->c[1] || s1_ptr->c[2] != s2_ptr->c[2] || s1_ptr->c[3] != s2_ptr->c[3] || + s1_ptr->c[4] != s2_ptr->c[4] || s1_ptr->c[5] != s2_ptr->c[5] || s1_ptr->c[6] != s2_ptr->c[6] || + s1_ptr->c[7] != s2_ptr->c[7] || s1_ptr->d != s2_ptr->d || s1_ptr->e != s2_ptr->e || + !H5_FLT_ABS_EQUAL(s1_ptr->f, s2_ptr->f) || !H5_FLT_ABS_EQUAL(s1_ptr->g, s2_ptr->g) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[0], s2_ptr->h[0]) || !H5_FLT_ABS_EQUAL(s1_ptr->h[1], s2_ptr->h[1]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[2], s2_ptr->h[2]) || !H5_FLT_ABS_EQUAL(s1_ptr->h[3], s2_ptr->h[3]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[4], s2_ptr->h[4]) || !H5_FLT_ABS_EQUAL(s1_ptr->h[5], s2_ptr->h[5]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[6], s2_ptr->h[6]) || !H5_FLT_ABS_EQUAL(s1_ptr->h[7], s2_ptr->h[7]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[8], s2_ptr->h[8]) || !H5_FLT_ABS_EQUAL(s1_ptr->h[9], s2_ptr->h[9]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[10], s2_ptr->h[10]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[11], s2_ptr->h[11]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[12], s2_ptr->h[12]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[13], s2_ptr->h[13]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[14], s2_ptr->h[14]) || + !H5_FLT_ABS_EQUAL(s1_ptr->h[15], s2_ptr->h[15]) || !H5_FLT_ABS_EQUAL(s1_ptr->i, s2_ptr->i) || + !H5_FLT_ABS_EQUAL(s1_ptr->j, s2_ptr->j) || !H5_DBL_ABS_EQUAL(s1_ptr->k, s2_ptr->k) || + !H5_DBL_ABS_EQUAL(s1_ptr->l, s2_ptr->l) || !H5_DBL_ABS_EQUAL(s1_ptr->m, s2_ptr->m) || + !H5_DBL_ABS_EQUAL(s1_ptr->n, s2_ptr->n) || s1_ptr->o != s2_ptr->o || s1_ptr->p != s2_ptr->p || + s1_ptr->q != s2_ptr->q) { + H5_FAILED(); + printf(" i=%d\n", i); + printf(" exp_buf={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, " + "h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, " + "o=%ld, p=%ld, q=%ld}\n", + s1_ptr->a, s1_ptr->b, s1_ptr->c[0], s1_ptr->c[1], s1_ptr->c[2], s1_ptr->c[3], s1_ptr->c[4], + s1_ptr->c[5], s1_ptr->c[6], s1_ptr->c[7], s1_ptr->d, s1_ptr->e, (double)s1_ptr->f, + (double)s1_ptr->g, (double)s1_ptr->h[0], (double)s1_ptr->h[1], (double)s1_ptr->h[2], + (double)s1_ptr->h[3], (double)s1_ptr->h[4], (double)s1_ptr->h[5], (double)s1_ptr->h[6], + (double)s1_ptr->h[7], (double)s1_ptr->h[8], (double)s1_ptr->h[9], (double)s1_ptr->h[10], + (double)s1_ptr->h[11], (double)s1_ptr->h[12], (double)s1_ptr->h[13], (double)s1_ptr->h[14], + (double)s1_ptr->h[15], (double)s1_ptr->i, (double)s1_ptr->j, s1_ptr->k, s1_ptr->l, + s1_ptr->m, s1_ptr->n, s1_ptr->o, s1_ptr->p, s1_ptr->q); + printf(" rbuf={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, " + "h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, " + "o=%ld, p=%ld, q=%ld}\n", + s2_ptr->a, s2_ptr->b, s2_ptr->c[0], s2_ptr->c[1], s2_ptr->c[2], s2_ptr->c[3], s2_ptr->c[4], + s2_ptr->c[5], s2_ptr->c[6], s2_ptr->c[7], s2_ptr->d, s2_ptr->e, (double)s2_ptr->f, + (double)s2_ptr->g, (double)s2_ptr->h[0], (double)s2_ptr->h[1], (double)s2_ptr->h[2], + (double)s2_ptr->h[3], (double)s2_ptr->h[4], (double)s2_ptr->h[5], (double)s2_ptr->h[6], + (double)s2_ptr->h[7], (double)s2_ptr->h[8], (double)s2_ptr->h[9], (double)s2_ptr->h[10], + (double)s2_ptr->h[11], (double)s2_ptr->h[12], (double)s2_ptr->h[13], (double)s2_ptr->h[14], + (double)s2_ptr->h[15], (double)s2_ptr->i, (double)s2_ptr->j, s2_ptr->k, s2_ptr->l, + s2_ptr->m, s2_ptr->n, s1_ptr->o, s1_ptr->p, s1_ptr->q); + + goto error; + } + } /* end for */ + + return SUCCEED; + +error: + return FAIL; + +} /* compare_stype4_data() */ + +/*------------------------------------------------------------------------- + * Function: compare_s1_data + * + * Purpose: Compare data (s1_t) read in rbuf with expected data in expect_buf. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_s1_data(void *expect_buf, void *rbuf) +{ + int i; + s1_t *s1_ptr; + s1_t *s2_ptr; + + /* Compare save_s1 with rbuf1. They should be the same */ + for (i = 0; i < (int)(NX * NY); i++) { + s1_ptr = ((s1_t *)expect_buf) + i; + s2_ptr = ((s1_t *)rbuf) + i; + + if (s1_ptr->a != s2_ptr->a || s1_ptr->b != s2_ptr->b || s1_ptr->c[0] != s2_ptr->c[0] || + s1_ptr->c[1] != s2_ptr->c[1] || s1_ptr->c[2] != s2_ptr->c[2] || s1_ptr->c[3] != s2_ptr->c[3] || + s1_ptr->d != s2_ptr->d || s1_ptr->e != s2_ptr->e) { + H5_FAILED(); + printf(" i=%d\n", i); + puts(" Incorrect values read from the file"); + goto error; + } + } + + return SUCCEED; + +error: + return FAIL; + +} /* compare_s1_data() */ + +/*------------------------------------------------------------------------- + * Function: compare_s1_s3_data + * + * Purpose: Compare data (s1_t/s3_t) read in rbuf with expected data in expect_buf. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_s1_s3_data(void *expect_buf, void *rbuf) +{ + int i; + s1_t *s1_ptr; + s3_t *s2_ptr; + + for (i = 0; i < (int)(NX * NY); i++) { + s1_ptr = ((s1_t *)expect_buf) + i; + s2_ptr = ((s3_t *)rbuf) + i; + + if (s1_ptr->a != s2_ptr->a || s1_ptr->b != s2_ptr->b || s1_ptr->c[0] != s2_ptr->c[0] || + s1_ptr->c[1] != s2_ptr->c[1] || s1_ptr->c[2] != s2_ptr->c[2] || s1_ptr->c[3] != s2_ptr->c[3] || + s1_ptr->d != s2_ptr->d || s1_ptr->e != s2_ptr->e) { + H5_FAILED(); + printf(" i=%d\n", i); + puts(" Incorrect values read from the file"); + goto error; + } + } + + return SUCCEED; + +error: + return FAIL; + +} /* compare_s1_s3_data() */ + +/*------------------------------------------------------------------------- + * Function: compare_s7_data + * + * Purpose: Compare data (s7_t) read in rbuf with expected data in expect_buf. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_s7_data(void *expect_buf, void *rbuf) +{ + int i; + s7_t *s1_ptr; + s7_t *s2_ptr; + + for (i = 0; i < (int)(NX * NY); i++) { + s1_ptr = ((s7_t *)expect_buf) + i; + s2_ptr = ((s7_t *)rbuf) + i; + + /* Compare only the data */ + if (s1_ptr->a != s2_ptr->a || s1_ptr->d != s2_ptr->d) { + H5_FAILED(); + printf(" i=%d\n", i); + printf(" expect_buf:a=%d, d=%d\n", s1_ptr->a, s1_ptr->d); + printf(" rbuf:a=%d, d=%d", s2_ptr->a, s2_ptr->d); + goto error; + } + } /* end for */ + + return SUCCEED; + +error: + return FAIL; + +} /* compare_s7_data() */ + +/*------------------------------------------------------------------------- + * Function: compare_s7_s8_data + * + * Purpose: Compare data read in rbuf with expected data + * in expect_buf: save_s7, save_s8. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_a_d_data(void *exp1_buf, void *exp2_buf, void *rbuf) +{ + int i; + s7_t *s1_ptr; + s8_t *s2_ptr; + s7_t *rbuf_ptr; + + for (i = 0; i < (int)(NX * NY); i++) { + s1_ptr = ((s7_t *)exp1_buf) + i; + s2_ptr = ((s8_t *)exp2_buf) + i; + rbuf_ptr = ((s7_t *)rbuf) + i; + + if (s2_ptr->a != rbuf_ptr->a || s1_ptr->d != rbuf_ptr->d) { + H5_FAILED(); + printf(" i=%d\n", i); + printf(" expect_buf:a=%d, d=%d\n", (int32_t)s2_ptr->a, s1_ptr->d); + printf(" rbuf: a=%d, d=%d", rbuf_ptr->a, rbuf_ptr->d); + goto error; + } + } /* end for */ + + return SUCCEED; + +error: + return FAIL; + +} /* compare_a_d_data() */ + +/*------------------------------------------------------------------------- + * Function: compare_a_b_c_data + * + * Purpose: Compare data read in rbuf with expected data + * in expect_buf: save_s8, save_rbuf8. + * + * Return: Success: 0 + * + * Failure: negative + * + *------------------------------------------------------------------------- + */ +static int +compare_a_b_c_data(void *exp1_buf, void *exp2_buf, void *rbuf) +{ + int i; + s8_t *s1_ptr; + s8_t *s2_ptr; + s8_t *rbuf_ptr; + + for (i = 0; i < (int)(NX * NY); i++) { + s1_ptr = ((s8_t *)exp1_buf) + i; + s2_ptr = ((s8_t *)exp2_buf) + i; + rbuf_ptr = ((s8_t *)rbuf) + i; + + if (s1_ptr->a != rbuf_ptr->a || s2_ptr->b != rbuf_ptr->b || s2_ptr->c != rbuf_ptr->c) { + H5_FAILED(); + printf(" i=%d\n", i); + printf(" expect_buf:a=%ld, b=%ld, c=%ld\n", s1_ptr->a, s2_ptr->b, s2_ptr->c); + printf(" rbuf: a=%ld, b=%ld, c=%ld", rbuf_ptr->a, rbuf_ptr->b, rbuf_ptr->c); + goto error; + } + } /* end for */ + + return SUCCEED; + +error: + return FAIL; + +} /* compare_a_b_c_data() */ + +/*------------------------------------------------------------------------- + * Function: test_select_src_subset + * + * Purpose: This is derived from test_hdf5_src_subset() for selection + * I/O testing: + * + * Test the optimization of compound data writing, rewriting, + * and reading when the source type is a subset of the destination + * type. For example: + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * + * Return: Success: 0 + * Failure: 1 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_select_src_subset(char *fname, hid_t fapl, hid_t in_dxpl, unsigned set_fillvalue, unsigned set_buf) +{ + hid_t fid = H5I_INVALID_HID; + hid_t rew_tid = H5I_INVALID_HID, src_tid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hsize_t dims[2] = {NX, NY}; + hsize_t chunk_dims[2] = {NX / 10, NY / 10}; + unsigned char *rew_buf = NULL, *save_rew_buf = NULL, *rbuf = NULL; + int fillvalue = (-1); + size_t ss, ss1, ss2; + + /* Create the file for this test */ + if ((fid = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + goto error; + + /* Build hdf5 datatypes */ + if ((src_tid = create_stype1()) < 0) + goto error; + + if ((rew_tid = create_stype3()) < 0) + goto error; + + /* Create the data space */ + if ((sid = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + + /* Allocate space and initialize data */ + rbuf = (unsigned char *)calloc(NX * NY, sizeof(stype3)); + + rew_buf = (unsigned char *)calloc(NX * NY, sizeof(stype3)); + initialize_stype3(rew_buf, (size_t)NX * NY); + + /* Save a copy as the buffer may be clobbered due to H5Pset_modify_write_buf() */ + save_rew_buf = (unsigned char *)calloc(NX * NY, sizeof(stype3)); + initialize_stype3(save_rew_buf, (size_t)NX * NY); + + /* Create dataset creation property list */ + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + /* + * Create contiguous and chunked datasets. + * Write to the datasets in a different compound subset order + */ + printf(" test_select_src_subset(): writing data to contiguous and chunked datasets"); + + if (set_fillvalue) { + if (H5Pset_fill_value(dcpl, src_tid, &fillvalue) < 0) + goto error; + } + + dxpl = H5Pcopy(in_dxpl); + if (set_buf) { + ss1 = H5Tget_size(rew_tid); + ss2 = H5Tget_size(src_tid); + ss = MAX(ss1, ss2) * NX * NY; + + if (H5Pset_buffer(dxpl, ss, NULL, NULL) < 0) + goto error; + } + + /* Create contiguous data set */ + if ((did = H5Dcreate2(fid, DSET_NAME[0], src_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Write to the dataset with rew_tid */ + if (H5Dwrite(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf) < 0) + goto error; + + if (H5Dread(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf) < 0) + goto error; + + if (memcmp(save_rew_buf, rbuf, sizeof(stype3) * NX * NY) != 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + /* Set chunking */ + if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + goto error; + + /* Create chunked data set */ + if ((did = H5Dcreate2(fid, DSET_NAME[1], src_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Write to the dataset with rew_tid */ + if (H5Dwrite(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf) < 0) + FAIL_STACK_ERROR; + + if (H5Dread(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf) < 0) + goto error; + + if (memcmp(save_rew_buf, rbuf, sizeof(stype3) * NX * NY) != 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + /* Finishing test and release resources */ + if (H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + + if (H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + + if (H5Pclose(dxpl) < 0) + FAIL_STACK_ERROR; + + if (H5Tclose(src_tid) < 0) + FAIL_STACK_ERROR; + + if (H5Tclose(rew_tid) < 0) + FAIL_STACK_ERROR; + + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + free(rbuf); + free(rew_buf); + free(save_rew_buf); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(dxpl); + H5Dclose(did); + H5Fclose(fid); + H5Tclose(src_tid); + H5Tclose(rew_tid); + } + H5E_END_TRY + + if (rbuf) + free(rbuf); + if (rew_buf) + free(rew_buf); + if (save_rew_buf) + free(save_rew_buf); + + printf("\n*** SELECT SRC SUBSET TEST FAILED ***\n"); + return 1; +} /* test_select_src_subset() */ + +/*------------------------------------------------------------------------- + * Function: test_select_dst_subset + * + * Purpose: This is derived from test_hdf5_dst_subset() for selection + * I/O testing: + + * Test the optimization of compound data writing, rewriting, + * and reading when the destination type is a subset of the + * source type. For example: + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * TYPE4 D; } + * TYPE5 E; + * }; + * + * Return: Success: 0 + * Failure: 1 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_select_dst_subset(char *fname, hid_t fapl, hid_t in_dxpl, unsigned set_fillvalue, unsigned set_buf) +{ + hid_t fid = H5I_INVALID_HID; + hid_t rew_tid = H5I_INVALID_HID, src_tid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hsize_t dims[2] = {NX, NY}; + hsize_t chunk_dims[2] = {NX / 10, NY / 10}; + unsigned char *rew_buf = NULL, *save_rew_buf = NULL, *rbuf = NULL; + int fillvalue = (-1); + size_t ss, ss1, ss2; + + /* Create the file for this test */ + if ((fid = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + goto error; + + /* Build hdf5 datatypes */ + if ((src_tid = create_stype2()) < 0) + goto error; + + if ((rew_tid = create_stype4()) < 0) + goto error; + + /* Create the data space */ + if ((sid = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + + rbuf = (unsigned char *)calloc(NX * NY, sizeof(stype4)); + + rew_buf = (unsigned char *)calloc(NX * NY, sizeof(stype4)); + initialize_stype4(rew_buf, (size_t)NX * NY); + + /* Save a copy as the buffer may be clobbered due to H5Pset_modify_write_buf() */ + save_rew_buf = (unsigned char *)calloc(NX * NY, sizeof(stype4)); + initialize_stype4(save_rew_buf, (size_t)NX * NY); + + /* Create dataset creation property list */ + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + /* + * Write data to contiguous and chunked datasets. + */ + printf(" test_select_dst_subset(): writing data to contiguous and chunked datasets"); + + if (set_fillvalue) { + if (H5Pset_fill_value(dcpl, src_tid, &fillvalue) < 0) + goto error; + } + + dxpl = H5Pcopy(in_dxpl); + if (set_buf) { + ss1 = H5Tget_size(rew_tid); + ss2 = H5Tget_size(src_tid); + ss = MAX(ss1, ss2) * NX * NY; + + if (H5Pset_buffer(dxpl, ss, NULL, NULL) < 0) + goto error; + } + + /* Create contiguous data set */ + if ((did = H5Dcreate2(fid, DSET_NAME[2], src_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Write to the dataset with rew_tid */ + if (H5Dwrite(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf) < 0) + goto error; + + /* Read from the dataset with rew_tid */ + if (H5Dread(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf) < 0) + goto error; + + if (compare_stype4_data(save_rew_buf, rbuf) < 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + /* Set chunking */ + if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + goto error; + + /* Create chunked data set */ + if ((did = H5Dcreate2(fid, DSET_NAME[3], src_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + initialize_stype4(rew_buf, (size_t)NX * NY); + + /* Write data to the dataset with rew_tid */ + if (H5Dwrite(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf) < 0) + goto error; + + /* Read frm the dataset with rew_tid */ + if (H5Dread(did, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf) < 0) + goto error; + + if (compare_stype4_data(save_rew_buf, rbuf) < 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + /* Finishing test and release resources */ + if (H5Sclose(sid) < 0) + goto error; + + if (H5Pclose(dcpl) < 0) + goto error; + + if (H5Pclose(dxpl) < 0) + FAIL_STACK_ERROR; + + if (H5Tclose(src_tid) < 0) + goto error; + + if (H5Tclose(rew_tid) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + free(rbuf); + free(rew_buf); + free(save_rew_buf); + + PASSED(); + return 0; -typedef struct { - int a, b, c[8], d, e; -} stype3; +error: + H5E_BEGIN_TRY + { + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(dxpl); + H5Dclose(did); + H5Fclose(fid); + H5Tclose(src_tid); + H5Tclose(rew_tid); + } + H5E_END_TRY -typedef struct { - int a, b, c[8], d, e; - float f, g, h[16], i, j; - double k, l, m, n; - long o, p, q; - long long r, s, t; -} stype4; + if (rbuf) + free(rbuf); + if (rew_buf) + free(rew_buf); + if (save_rew_buf) + free(save_rew_buf); -#define NX 100U -#define NY 2000U -#define PACK_NMEMBS 100 + printf("\n*** SELECT DST SUBSET TEST FAILED ***\n"); + return 1; +} /* test_select_dst_subset */ + +/*------------------------------------------------------------------------- + * Function: test_select_compound + * + * Purpose: This is derived from test_comppound() for selection I/O + * testing: + * + * --Creates a simple dataset of a compound type and then + * writes it in original and reverse order. + * --Creates another dataset to verify the CI window + * is fixed. + * + * Return: Success: 0 + * Failure: 1 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_select_compound(char *fname, hid_t fapl, hid_t in_dxpl, unsigned set_fillvalue, unsigned set_buf) +{ + hid_t s1_tid = H5I_INVALID_HID; + hid_t s3_tid = H5I_INVALID_HID; + hid_t s7_tid = H5I_INVALID_HID; + hid_t s8_tid = H5I_INVALID_HID; + + /* Buffers */ + s1_t *s1 = NULL; + s1_t *save_s1 = NULL; + s3_t *s3 = NULL; + s3_t *save_s3 = NULL; + s1_t *rbuf1 = NULL; + s3_t *rbuf3 = NULL; + + s7_t *s7 = NULL; + s7_t *save_s7 = NULL; + s7_t *rbuf7 = NULL; + + s8_t *s8 = NULL; + s8_t *save_s8 = NULL; + s8_t *rbuf8 = NULL; + s8_t *save_rbuf8 = NULL; + + /* Other variables */ + unsigned int i; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t array_dt = H5I_INVALID_HID; + static hsize_t dim[] = {NX, NY}; + int fillvalue = (-1); + size_t ss = 0, ss1 = 0, ss2 = 0; + hsize_t memb_size[1] = {4}; + + /* Allocate buffers */ + if (NULL == (s1 = (s1_t *)calloc(NX * NY, sizeof(s1_t)))) + goto error; + if (NULL == (save_s1 = (s1_t *)calloc(NX * NY, sizeof(s1_t)))) + goto error; + if (NULL == (rbuf1 = (s1_t *)calloc(NX * NY, sizeof(s1_t)))) + goto error; + if (NULL == (s3 = (s3_t *)calloc(NX * NY, sizeof(s3_t)))) + goto error; + if (NULL == (save_s3 = (s3_t *)calloc(NX * NY, sizeof(s3_t)))) + goto error; + if (NULL == (rbuf3 = (s3_t *)calloc(NX * NY, sizeof(s3_t)))) + goto error; + + if (NULL == (s7 = (s7_t *)calloc(NX * NY, sizeof(s7_t)))) + goto error; + if (NULL == (save_s7 = (s7_t *)calloc(NX * NY, sizeof(s7_t)))) + goto error; + if (NULL == (rbuf7 = (s7_t *)calloc(NX * NY, sizeof(s7_t)))) + goto error; + + if (NULL == (s8 = (s8_t *)calloc(NX * NY, sizeof(s8_t)))) + goto error; + if (NULL == (save_s8 = (s8_t *)calloc(NX * NY, sizeof(s8_t)))) + goto error; + if (NULL == (rbuf8 = (s8_t *)calloc(NX * NY, sizeof(s8_t)))) + goto error; + if (NULL == (save_rbuf8 = (s8_t *)calloc(NX * NY, sizeof(s8_t)))) + goto error; + + /* Create the file */ + if ((fid = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { + goto error; + } + + /* Create the data space */ + if ((sid = H5Screate_simple(2, dim, NULL)) < 0) + goto error; + + /* Create dataset creation property list */ + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + /* Create a copy of the incoming dataset transfer property list */ + if ((dxpl = H5Pcopy(in_dxpl)) < 0) + goto error; + + /* + * Create and write to the dataset in original compound struct members order + */ + printf(" test_select_compound(): basic compound write"); + + /* Initialize buffer with s1_t */ + for (i = 0; i < NX * NY; i++) { + s1[i].a = 8 * i + 0; + s1[i].b = 2000 + 2 * i; + s1[i].c[0] = 8 * i + 2; + s1[i].c[1] = 8 * i + 3; + s1[i].c[2] = 8 * i + 4; + s1[i].c[3] = 8 * i + 5; + s1[i].d = 2001 + 2 * i; + s1[i].e = 8 * i + 7; + } + memcpy(save_s1, s1, sizeof(s1_t) * NX * NY); + + /* Create file type s1_t */ + if ((s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + goto error; + array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, memb_size); + if (H5Tinsert(s1_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "c", HOFFSET(s1_t, c), array_dt) < 0 || + H5Tinsert(s1_tid, "d", HOFFSET(s1_t, d), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "e", HOFFSET(s1_t, e), H5T_NATIVE_INT) < 0) + goto error; + H5Tclose(array_dt); + + /* Set fill value accordingly */ + if (set_fillvalue) { + if (H5Pset_fill_value(dcpl, s1_tid, &fillvalue) < 0) + goto error; + } + + /* Create the dataset with file type s1_tid */ + if ((did = H5Dcreate2(fid, "s1", s1_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Set buffer size accordingly */ + if (set_buf) { + ss1 = H5Tget_size(s1_tid); + + if (H5Pset_buffer(dxpl, ss1, NULL, NULL) < 0) + goto error; + } + + /* Write to the dataset with file type s1_tid */ + if (H5Dwrite(did, s1_tid, H5S_ALL, H5S_ALL, dxpl, s1) < 0) + goto error; + + /* Read from the dataset with file type s1_tid */ + if (H5Dread(did, s1_tid, H5S_ALL, H5S_ALL, dxpl, rbuf1) < 0) + goto error; + + /* Verify data is correct */ + if (compare_s1_data(save_s1, rbuf1) < 0) + goto error; + + PASSED(); + + /* + * Write to the dataset with s3 memory buffer. This buffer + * has the same data space but the data type is different: the + * data type is a struct whose members are in the opposite order. + */ + printf(" test_select_compound(): reversal of struct members"); + + /* Create mem type s3_tid */ + if ((s3_tid = H5Tcreate(H5T_COMPOUND, sizeof(s3_t))) < 0) + goto error; + array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, memb_size); + if (H5Tinsert(s3_tid, "a", HOFFSET(s3_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "b", HOFFSET(s3_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "c", HOFFSET(s3_t, c), array_dt) < 0 || + H5Tinsert(s3_tid, "d", HOFFSET(s3_t, d), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "e", HOFFSET(s3_t, e), H5T_NATIVE_INT) < 0) + goto error; + H5Tclose(array_dt); + + /* Initialize buffer with s3_t */ + for (i = 0; i < NX * NY; i++) { + s3[i].a = 8 * i + 0; + s3[i].b = 2000 + 2 * i; + s3[i].c[0] = 8 * i + 2; + s3[i].c[1] = 8 * i + 3; + s3[i].c[2] = 8 * i + 4; + s3[i].c[3] = 8 * i + 5; + s3[i].d = 2001 + 2 * i; + s3[i].e = 8 * i + 7; + } + + memcpy(save_s3, s3, sizeof(s3_t) * NX * NY); + + /* Set buffer size accordingly */ + if (set_buf) { + /* ss1 is set already previously */ + ss2 = H5Tget_size(s3_tid); + ss = MAX(ss1, ss2) * NX * NY; + + if (H5Pset_buffer(dxpl, ss, NULL, NULL) < 0) + goto error; + } + + /* Read from the dataset with mem type s3_tid */ + if (H5Dread(did, s3_tid, H5S_ALL, H5S_ALL, dxpl, rbuf3) < 0) + goto error; + + if (compare_s1_s3_data(save_s1, rbuf3) < 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + PASSED(); + + printf(" test_select_compound(): verify fix for non-optimized compound conversions with memory type " + "larger than file "); + + /* Create file type s7_tid */ + if ((s7_tid = H5Tcreate(H5T_COMPOUND, sizeof(s7_t))) < 0) + goto error; + + if (H5Tinsert(s7_tid, "a", HOFFSET(s7_t, a), H5T_NATIVE_INT32) < 0 || + H5Tinsert(s7_tid, "d", HOFFSET(s7_t, d), H5T_NATIVE_INT32) < 0) + goto error; + + /* Initialize buffer with s7_t */ + for (i = 0; i < NX * NY; i++) { + s7[i].a = (int32_t)(2 * i); + s7[i].d = (int32_t)(2 * i + 1); + } + memcpy(save_s7, s7, sizeof(s7_t) * NX * NY); + + /* Create mem type s8_tid */ + if ((s8_tid = H5Tcreate(H5T_COMPOUND, sizeof(s8_t))) < 0) + goto error; + + if (H5Tinsert(s8_tid, "a", HOFFSET(s8_t, a), H5T_NATIVE_INT64) < 0 || + H5Tinsert(s8_tid, "b", HOFFSET(s8_t, b), H5T_NATIVE_INT64) < 0 || + H5Tinsert(s8_tid, "c", HOFFSET(s8_t, c), H5T_NATIVE_INT64) < 0) + goto error; + + /* Initialize buffer with s8_t */ + for (i = 0; i < NX * NY; i++) { + s8[i].a = (int64_t)(2 * NX * NY + 3 * i); + s8[i].b = (int64_t)(2 * NX * NY + 3 * i + 1); + s8[i].c = (int64_t)(2 * NX * NY + 3 * i + 2); + } + memcpy(save_s8, s8, sizeof(s8_t) * NX * NY); + + /* Set fill value accordingly */ + if (set_fillvalue) { + if (H5Pset_fill_value(dcpl, s7_tid, &fillvalue) < 0) + goto error; + } + + /* Set buffer size accordingly */ + if (set_buf) { + ss1 = H5Tget_size(s7_tid); + ss2 = H5Tget_size(s8_tid); + ss = MAX(ss1, ss2) * NX * NY; + + if (H5Pset_buffer(dxpl, ss, NULL, NULL) < 0) + goto error; + } + + /* Create dataset with file type s7_tid */ + if ((did = H5Dcreate2(fid, "ss", s7_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Write to the dataset with mem type s7_tid */ + if (H5Dwrite(did, s7_tid, H5S_ALL, H5S_ALL, dxpl, s7) < 0) + goto error; + + /* Read from the dataset with mem type s7_tid */ + if (H5Dread(did, s7_tid, H5S_ALL, H5S_ALL, dxpl, rbuf7) < 0) + goto error; + + /* Verify data read is correct */ + if (compare_s7_data(save_s7, rbuf7) < 0) + goto error; + + /* Write to the dataset with mem type s8_tid */ + if (H5Dwrite(did, s8_tid, H5S_ALL, H5S_ALL, dxpl, s8) < 0) + goto error; + + /* Read from the dataset with mem type s7_tid */ + memset(rbuf7, 0, NX * NY * sizeof(s7_t)); + if (H5Dread(did, s7_tid, H5S_ALL, H5S_ALL, dxpl, rbuf7) < 0) + goto error; + + /* Verify a: save_s8, d: save_s7 */ + if (compare_a_d_data(save_s7, save_s8, rbuf7) < 0) + goto error; + + /* Initialize read buffer of s8_t with unique values */ + for (i = 0; i < NX * NY; i++) { + rbuf8[i].a = (int64_t)(5 * NX * NY + 3 * i); + rbuf8[i].b = (int64_t)(5 * NX * NY + 3 * i + 1); + rbuf8[i].c = (int64_t)(5 * NX * NY + 3 * i + 2); + } + memcpy(save_rbuf8, rbuf8, sizeof(s8_t) * NX * NY); + + /* Read from the dataset with mem type s8_tid */ + if (H5Dread(did, s8_tid, H5S_ALL, H5S_ALL, dxpl, rbuf8) < 0) + goto error; + + /* Verify a: save_s8; b, c: save_rbuf8 */ + if (compare_a_b_c_data(save_s8, save_rbuf8, rbuf8) < 0) + goto error; + + if (H5Dclose(did) < 0) + goto error; + + PASSED(); + + /* + * Release resources. + */ + if (H5Sclose(sid) < 0) + goto error; + + if (H5Pclose(dcpl) < 0) + goto error; + + if (H5Pclose(dxpl) < 0) + goto error; + + if (H5Tclose(s1_tid) < 0) + goto error; + + if (H5Tclose(s3_tid) < 0) + goto error; + + if (H5Tclose(s7_tid) < 0) + goto error; + + if (H5Tclose(s8_tid) < 0) + goto error; + + if (H5Fclose(fid) < 0) + goto error; + + /* Release buffers */ + free(s1); + free(s3); + free(save_s3); + free(rbuf1); + free(rbuf3); + free(s7); + free(save_s7); + free(s8); + free(save_s8); + free(rbuf7); + free(rbuf8); + free(save_rbuf8); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(dxpl); + H5Dclose(did); + H5Fclose(fid); + H5Tclose(s1_tid); + H5Tclose(s3_tid); + H5Tclose(s7_tid); + H5Tclose(s8_tid); + } + H5E_END_TRY + + /* Release resources */ + if (s1) + free(s1); + if (s3) + free(s3); + if (save_s3) + free(save_s3); + if (rbuf1) + free(rbuf1); + if (rbuf3) + free(rbuf3); + if (s7) + free(s7); + if (save_s7) + free(save_s7); + if (s8) + free(s8); + if (save_s8) + free(save_s8); + if (rbuf7) + free(rbuf7); + if (rbuf8) + free(rbuf8); + if (save_rbuf8) + free(save_rbuf8); + + printf("\n*** SELECT COMPOUND DATASET TESTS FAILED ***\n"); + return 1; +} /* test_select_compound() */ + +/* + * Purpose: Tests for selection I/O with compound types: + * --set_cache: set chunk cache to 0 or not + * via H5Pset_cache(fapl...) + * --set_fillvalue: set fill value or not + * via H5Pset_fill_value(dcpl...) + * --select_io: enable selection I/O or not + * via H5Pset_selection_io(dxpl...) + * --mwbuf: with or without modifying write buffers + * via H5Pset_modify_write_buf(dxpl...) + * --set_buf: with or without setting the maximum size + * for the type conversion buffer and background buffer + * via H5Pset_buffer(dxpl...) + * + * These tests will test the selection I/O pipeline in particular + * triggering H5D__scatgath_read()/write(), + * H5D__scatgath_write_select_read()/write(), + * and with/without the optimized compound read/write. + */ +static unsigned +test_compounds_selection_io(void) +{ + unsigned nerrs = 0; + unsigned set_cache; /* Set cache to 0 or not */ + unsigned set_fillvalue; /* Set fill value or not */ + unsigned select_io; /* Enable selection I/O or not */ + unsigned mwbuf; /* With or without modifying write buffers */ + unsigned set_buf; /* With or without H5Pset_buffer */ + hid_t fapl = -1; + hid_t dxpl = -1; + char fname[256]; + + fapl = h5_fileaccess(); + h5_fixname(FILENAME[3], fapl, fname, sizeof(fname)); + + for (set_cache = FALSE; set_cache <= TRUE; set_cache++) { + for (set_fillvalue = FALSE; set_fillvalue <= TRUE; set_fillvalue++) { + for (select_io = FALSE; select_io <= TRUE; select_io++) { + for (mwbuf = FALSE; mwbuf <= TRUE; mwbuf++) { + for (set_buf = FALSE; set_buf <= TRUE; set_buf++) { + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + if (set_cache) { + printf(" With chunk cache set 0, "); + if (H5Pset_cache(fapl, 0, (size_t)0, (size_t)0, 0.0) < 0) + goto error; + } + else + printf(" With default chunk cache, "); + + if (set_fillvalue) + printf("set fill value, "); + else + printf("not set fill value, "); + + if (select_io) { + printf("selection I/O ON, "); + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) + goto error; + } + else + printf("selection I/O OFF, "); + + if (mwbuf) { + printf("with modify write buf, "); + if (H5Pset_modify_write_buf(dxpl, TRUE) < 0) + goto error; + } + else + printf("without modify write buf, "); + + if (set_buf) + printf("with H5Pset_buffer:\n"); + else + printf("without H5Pset_buffer:\n"); + + nerrs += test_select_compound(fname, fapl, dxpl, set_fillvalue, set_buf); + nerrs += test_select_src_subset(fname, fapl, dxpl, set_fillvalue, set_buf); + nerrs += test_select_dst_subset(fname, fapl, dxpl, set_fillvalue, set_buf); + + if (H5Pclose(dxpl) < 0) + goto error; + + } /* set_buf */ + } /* mwbuf */ + } /* select_io */ + } /* set_fillvalue */ + } /* set_cache */ + + if (H5Pclose(fapl) < 0) + goto error; + + if (nerrs) + goto error; + + return 0; + +error: + printf("*** COMPOUNDS TESTS FOR SELECTION I/O FAILED ***"); + + return 1; +} /* test_compounds_selection_io() */ /*------------------------------------------------------------------------- * Function: test_compound @@ -1220,7 +2389,7 @@ compare_data(void *src_data, void *dst_data, bool src_subset) * Function: test_hdf5_src_subset * * Purpose: Test the optimization of compound data writing, rewriting, - * and reading when the source type is a subset of destination + * and reading when the source type is a subset of the destination * type. For example: * struct source { struct destination { * TYPE1 A; --> TYPE1 A; @@ -1432,7 +2601,7 @@ test_hdf5_src_subset(char *filename, hid_t fapl) * TYPE5 E; * }; * This optimization is for the Chicago company. This test - * is in opposite of test_hdf5_src_subset. + * is the opposite of test_hdf5_src_subset. * * Return: Success: 0 * @@ -2173,6 +3342,9 @@ main(int argc, char *argv[]) (H5T_conv_t)((void (*)(void))H5T__conv_struct_opt)); } + printf("Testing compound dataset for selection I/O cases----\n"); + nerrors += test_compounds_selection_io(); + /* Create the file */ fapl_id = h5_fileaccess(); diff --git a/test/select_io_dset.c b/test/select_io_dset.c index d75b76becdb..79449aac070 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -265,6 +265,7 @@ test_no_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) char *wbuf_bak = NULL; char *rbuf = NULL; char dset_name[DSET_NAME_LEN]; + int fillvalue = (-1); if ((wbuf = (char *)malloc((size_t)(4 * DSET_SELECT_DIM))) == NULL) FAIL_STACK_ERROR; @@ -289,9 +290,13 @@ test_no_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) dims[0] = DSET_SELECT_DIM; if ((sid = H5Screate_simple(1, dims, NULL)) < 0) FAIL_STACK_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR; + if (H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillvalue) < 0) + FAIL_STACK_ERROR; + if (chunked) { cdims[0] = DSET_SELECT_CHUNK_DIM; if (H5Pset_chunk(dcpl, 1, cdims) < 0) @@ -721,6 +726,7 @@ test_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) s2_t *s2_wbuf_bak = NULL; s2_t *s2_rbuf = NULL; char dset_name[DSET_NAME_LEN]; + int fillvalue = -1; /* Create dataset transfer property list */ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) @@ -762,9 +768,13 @@ test_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) dims[0] = DSET_SELECT_DIM; if ((sid = H5Screate_simple(1, dims, NULL)) < 0) FAIL_STACK_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR; + if (H5Pset_fill_value(dcpl, s1_tid, &fillvalue) < 0) + FAIL_STACK_ERROR; + if (chunked) { cdims[0] = DSET_SELECT_CHUNK_DIM; if (H5Pset_chunk(dcpl, 1, cdims) < 0) @@ -2729,8 +2739,9 @@ test_multi_dsets_all(int niter, hid_t fid, unsigned chunked, unsigned mwbuf) * Verify H5Pset/get_selection_io API works as expected */ static herr_t -test_set_get_select_io_mode(hid_t fid) +test_set_get_select_io_mode(const char *filename, hid_t fapl) { + hid_t fid = H5I_INVALID_HID; hid_t did = H5I_INVALID_HID; hid_t sid = H5I_INVALID_HID; hid_t dcpl = H5I_INVALID_HID; @@ -2744,6 +2755,9 @@ test_set_get_select_io_mode(hid_t fid) printf("\n"); TESTING("H5Pget/set_selection_io_mode()"); + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR; + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR; @@ -2808,6 +2822,8 @@ test_set_get_select_io_mode(hid_t fid) FAIL_STACK_ERROR; if (H5Sclose(sid) < 0) FAIL_STACK_ERROR; + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; PASSED(); @@ -2820,6 +2836,7 @@ test_set_get_select_io_mode(hid_t fid) H5Dclose(did); H5Pclose(dcpl); H5Pclose(dxpl); + H5Fclose(fid); } H5E_END_TRY @@ -3123,150 +3140,176 @@ main(void) { int nerrors = 0; char filename[FILENAME_BUF_SIZE]; - hid_t fapl = H5I_INVALID_HID; - hid_t fid = H5I_INVALID_HID; + hid_t fapl = H5I_INVALID_HID; + hid_t fapl2 = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; int test_select_config; - unsigned chunked; - unsigned dtrans; - unsigned mwbuf; + unsigned set_cache; /* Set chunk cache to 0 or not */ + unsigned chunked; /* Set to chunked dataset or not */ + unsigned dtrans; /* Set to using data transform or not */ + unsigned mwbuf; /* With/without modifying write buffer */ /* Testing setup */ h5_reset(); fapl = h5_fileaccess(); - h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + if ((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR; - /* Test with contiguous or chunked dataset */ - for (chunked = false; chunked <= true; chunked++) { + for (set_cache = FALSE; set_cache <= TRUE; set_cache++) { - /* Data transforms only apply to integer or floating-point datasets */ - /* therefore, not all tests are run with data transform */ - for (dtrans = false; dtrans <= true; dtrans++) { + /* Disable chunk caching on fapl2 */ + if (set_cache) { + if (H5Pset_cache(fapl2, 0, (size_t)0, (size_t)0, 0.0) < 0) + TEST_ERROR; + } - /* Test with and without modify_write_buf turned on */ - for (mwbuf = false; mwbuf <= true; mwbuf++) { - /* Print configuration message */ - printf("Testing for selection I/O "); - if (chunked) - printf("with chunked dataset, "); - else - printf("with contiguous dataset, "); - if (dtrans) - printf("data transform, "); - else - printf("without data transform, "); - if (mwbuf) - printf("and with modifying write buffers\n"); - else - printf("and without modifying write buffers\n"); + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl2)) < 0) + TEST_ERROR; - for (test_select_config = (int)TEST_NO_TYPE_CONV; - test_select_config < (int)TEST_SELECT_NTESTS; test_select_config++) { + /* Test with contiguous or chunked dataset */ + for (chunked = false; chunked <= true; chunked++) { - switch (test_select_config) { - case TEST_NO_TYPE_CONV: /* case 1 */ - TESTING_2("No type conversion (null case)"); + /* Data transforms only apply to integer or floating-point datasets */ + /* therefore, not all tests are run with data transform */ + for (dtrans = false; dtrans <= true; dtrans++) { - nerrors += (test_no_type_conv(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); + /* Test with and without modify_write_buf turned on */ + for (mwbuf = false; mwbuf <= true; mwbuf++) { - break; + /* Print configuration message */ + printf("Testing for selection I/O "); - case TEST_NO_SIZE_CHANGE_NO_BKG: /* case 2 */ - TESTING_2("No size change, no background buffer"); + if (set_cache) + printf("with 0 chunk cache, "); + else + printf("with default chunk cache, "); - /* Data transforms does not apply to the dataset datatype for this test */ - if (dtrans) - SKIPPED(); - else - nerrors += (test_no_size_change_no_bkg(fid, chunked, mwbuf) < 0 ? 1 : 0); + if (chunked) + printf("with chunked dataset, "); + else + printf("with contiguous dataset, "); - break; + if (dtrans) + printf("data transform, "); + else + printf("without data transform, "); - case TEST_LARGER_MEM_NO_BKG: /* case 3 */ - TESTING_2("Larger memory type, no background buffer"); + if (mwbuf) + printf("and with modifying write buffers\n"); + else + printf("and without modifying write buffers\n"); - nerrors += (test_larger_mem_type_no_bkg(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); + for (test_select_config = (int)TEST_NO_TYPE_CONV; + test_select_config < (int)TEST_SELECT_NTESTS; test_select_config++) { - break; + switch (test_select_config) { + case TEST_NO_TYPE_CONV: /* case 1 */ + TESTING_2("No type conversion (null case)"); - case TEST_SMALLER_MEM_NO_BKG: /* case 4 */ - TESTING_2("Smaller memory type, no background buffer"); + nerrors += (test_no_type_conv(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); - nerrors += - (test_smaller_mem_type_no_bkg(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); + break; - break; + case TEST_NO_SIZE_CHANGE_NO_BKG: /* case 2 */ + TESTING_2("No size change, no background buffer"); - case TEST_CMPD_WITH_BKG: /* case 5 */ - TESTING_2("Compound types with background buffer"); + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) + SKIPPED(); + else + nerrors += (test_no_size_change_no_bkg(fid, chunked, mwbuf) < 0 ? 1 : 0); - /* Data transforms does not apply to the dataset datatype for this test */ - if (dtrans) - SKIPPED(); - else - nerrors += (test_cmpd_with_bkg(fid, chunked, mwbuf) < 0 ? 1 : 0); + break; - break; + case TEST_LARGER_MEM_NO_BKG: /* case 3 */ + TESTING_2("Larger memory type, no background buffer"); - case TEST_MULTI_CONV_NO_BKG: /* case 6 */ - TESTING_2("multi-datasets: type conv + no bkg buffer"); + nerrors += + (test_larger_mem_type_no_bkg(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); - nerrors += test_multi_dsets_no_bkg(fid, chunked, dtrans, mwbuf); - break; + break; - case TEST_MULTI_CONV_BKG: /* case 7 */ - TESTING_2("multi-datasets: type conv + bkg buffer"); + case TEST_SMALLER_MEM_NO_BKG: /* case 4 */ + TESTING_2("Smaller memory type, no background buffer"); - /* Data transforms does not apply to the dataset datatype for this test */ - if (dtrans) - SKIPPED(); - else - nerrors += test_multi_dsets_cmpd_with_bkg(fid, chunked, mwbuf); + nerrors += + (test_smaller_mem_type_no_bkg(fid, chunked, dtrans, mwbuf) < 0 ? 1 : 0); - break; + break; - case TEST_MULTI_CONV_SIZE_CHANGE: /* case 8 */ - TESTING_2("multi-datasets: type conv + size change + no bkg buffer"); + case TEST_CMPD_WITH_BKG: /* case 5 */ + TESTING_2("Compound types with background buffer"); - /* Data transforms does not apply to the dataset datatype for this test */ - if (dtrans) - SKIPPED(); - else - nerrors += test_multi_dsets_size_change_no_bkg(fid, chunked, mwbuf); + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) + SKIPPED(); + else + nerrors += (test_cmpd_with_bkg(fid, chunked, mwbuf) < 0 ? 1 : 0); - break; + break; - case TEST_MULTI_ALL: /* case 9 */ - TESTING_2("multi-datasets: no conv + conv without bkg + conv with bkg"); + case TEST_MULTI_CONV_NO_BKG: /* case 6 */ + TESTING_2("multi-datasets: type conv + no bkg buffer"); - /* Data transforms does not apply to the dataset datatype for this test */ - if (dtrans) - SKIPPED(); - else - nerrors += test_multi_dsets_all(10, fid, chunked, mwbuf); + nerrors += test_multi_dsets_no_bkg(fid, chunked, dtrans, mwbuf); - break; + break; - case TEST_SELECT_NTESTS: - default: - TEST_ERROR; + case TEST_MULTI_CONV_BKG: /* case 7 */ + TESTING_2("multi-datasets: type conv + bkg buffer"); - } /* end switch */ - } /* end for test_select_config */ + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) + SKIPPED(); + else + nerrors += test_multi_dsets_cmpd_with_bkg(fid, chunked, mwbuf); - } /* end mwbuf */ + break; - } /* end dtrans */ + case TEST_MULTI_CONV_SIZE_CHANGE: /* case 8 */ + TESTING_2("multi-datasets: type conv + size change + no bkg buffer"); - } /* end chunked */ + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) + SKIPPED(); + else + nerrors += test_multi_dsets_size_change_no_bkg(fid, chunked, mwbuf); - nerrors += test_set_get_select_io_mode(fid); + break; - if (H5Fclose(fid) < 0) - TEST_ERROR; + case TEST_MULTI_ALL: /* case 9 */ + TESTING_2("multi-datasets: no conv + conv without bkg + conv with bkg"); + + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) + SKIPPED(); + else + nerrors += test_multi_dsets_all(10, fid, chunked, mwbuf); + + break; + + case TEST_SELECT_NTESTS: + default: + TEST_ERROR; + + } /* end switch */ + } /* end for test_select_config */ + + } /* end mwbuf */ + + } /* end dtrans */ + + } /* end chunked */ + + if (H5Fclose(fid) < 0) + TEST_ERROR; + + } /* end set_cache */ + + /* Use own file */ + nerrors += test_set_get_select_io_mode(filename, fapl); /* Use own file */ nerrors += test_get_no_selection_io_cause(filename, fapl);