From 09b1106e39edc1d2fa7c92c9c8de57d8c01e4e71 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 30 Apr 2018 07:52:07 -0700 Subject: First stage of moving H5DOread/write_chunk() to src/ and making them H5D calls. * Moved H5DOread/write_chunk() to H5Dio.c and renamed to H5D*. * Moved the hl/test/test_dset_opt test to test/ and renamed to direct_chunk. * Moved the hl/test/dectris_hl_perf test to tools/test/perform and renamed to direct_write_perf. * Updated autotools and CMake files. --- hl/src/H5DO.c | 227 +--- hl/src/H5DOpublic.h | 9 - hl/test/CMakeLists.txt | 1 - hl/test/CMakeTests.cmake | 2 - hl/test/Makefile.am | 5 +- hl/test/dectris_hl_perf.c | 691 ---------- hl/test/test_dset_opt.c | 2171 -------------------------------- src/H5Dio.c | 155 ++- src/H5Dpublic.h | 4 + test/CMakeLists.txt | 1 + test/CMakeTests.cmake | 1 + test/Makefile.am | 13 +- test/direct_chunk.c | 2167 +++++++++++++++++++++++++++++++ tools/test/perform/direct_write_perf.c | 684 ++++++++++ 14 files changed, 3058 insertions(+), 3073 deletions(-) delete mode 100644 hl/test/dectris_hl_perf.c delete mode 100644 hl/test/test_dset_opt.c create mode 100644 test/direct_chunk.c create mode 100644 tools/test/perform/direct_write_perf.c diff --git a/hl/src/H5DO.c b/hl/src/H5DO.c index 99cf2f7..20d5a4a 100644 --- a/hl/src/H5DO.c +++ b/hl/src/H5DO.c @@ -22,163 +22,20 @@ /* public LT prototypes */ #include "H5DOpublic.h" - /*------------------------------------------------------------------------- - * Function: H5DOwrite_chunk - * - * Purpose: Writes an entire chunk to the file directly. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * 30 July 2012 + * Function: H5DOappend() * - *------------------------------------------------------------------------- - */ -herr_t -H5DOwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, - size_t data_size, const void *buf) -{ - hbool_t created_dxpl = FALSE; /* Whether we created a DXPL */ - hbool_t do_direct_write = TRUE; /* Flag for direct writes */ - uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ - herr_t ret_value = FAIL; /* Return value */ - - /* Check arguments */ - if(dset_id < 0) - goto done; - if(!buf) - goto done; - if(!offset) - goto done; - if(!data_size) - goto done; - data_size_32 = (uint32_t)data_size; - if(data_size != (size_t)data_size_32) - goto done; - - /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ - if(H5P_DEFAULT == dxpl_id) { - if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto done; - created_dxpl = TRUE; - } /* end if */ - - /* Set direct write parameters */ - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &do_direct_write) < 0) - goto done; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME, &filters) < 0) - goto done; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME, &offset) < 0) - goto done; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME, &data_size_32) < 0) - goto done; - - /* Write chunk */ - if(H5Dwrite(dset_id, 0, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) - goto done; - - /* Indicate success */ - ret_value = SUCCEED; - -done: - if(created_dxpl) { - if(H5Pclose(dxpl_id) < 0) - ret_value = FAIL; - } /* end if */ - else { - /* Reset the direct write flag on user DXPL */ - do_direct_write = FALSE; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &do_direct_write) < 0) - ret_value = FAIL; - } - - return ret_value; -} /* end H5DOwrite_chunk() */ - - -/*------------------------------------------------------------------------- - * Function: H5DOread_chunk + * Purpose: To append elements to a dataset. * - * Purpose: Reads an entire chunk from the file directly. + * axis: the dataset dimension (zero-based) for the append + * extension: the # of elements to append for the axis-th dimension + * memtype: the datatype + * buf: buffer with data for the append * * Return: Non-negative on success/Negative on failure * - * Programmer: Matthew Strong (GE Healthcare) - * 14 February 2016 - * - *--------------------------------------------------------------------------- - */ -herr_t -H5DOread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, - void *buf) -{ - hbool_t created_dxpl = FALSE; /* Whether we created a DXPL */ - hbool_t do_direct_read = TRUE; /* Flag for direct writes */ - herr_t ret_value = FAIL; /* Return value */ - - /* Check arguments */ - if(dset_id < 0) - goto done; - if(!buf) - goto done; - if(!offset) - goto done; - if(!filters) - goto done; - - /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ - if(H5P_DEFAULT == dxpl_id) { - if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto done; - created_dxpl = TRUE; - } /* end if */ - - /* Set direct write parameters */ - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FLAG_NAME, &do_direct_read) < 0) - goto done; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_OFFSET_NAME, &offset) < 0) - goto done; - - /* Read chunk */ - if(H5Dread(dset_id, 0, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) - goto done; - /* Get the filter mask */ - if(H5Pget(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FILTERS_NAME, filters) < 0) - goto done; - - /* Indicate success */ - ret_value = SUCCEED; - -done: - if(created_dxpl) { - if(H5Pclose(dxpl_id) < 0) - ret_value = FAIL; - } /* end if */ - else { - /* Reset the direct read flag on user DXPL */ - do_direct_read = FALSE; - if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FLAG_NAME, &do_direct_read) < 0) - ret_value = FAIL; - } - - return ret_value; -} /* end H5DOread_chunk() */ - - -/*------------------------------------------------------------------------- - * Function: H5DOappend() - * - * Purpose: To append elements to a dataset. - * axis: the dataset dimension (zero-based) for the append - * extension: the # of elements to append for the axis-th dimension - * memtype: the datatype - * buf: buffer with data for the append - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Vailin Choi; Jan 2014 + * Programmer: Vailin Choi; Jan 2014 * * Note: * This routine is copied from the fast forward feature branch: features/hdf5_ff @@ -227,7 +84,7 @@ H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, /* check arguments */ if(H5I_DATASET != H5Iget_type(dset_id)) - goto done; + goto done; /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ if(H5P_DEFAULT == dxpl_id) { @@ -236,35 +93,35 @@ H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, created_dxpl = TRUE; } /* end if */ else if(TRUE != H5Pisa_class(dxpl_id, H5P_DATASET_XFER)) - goto done; + goto done; /* Get the dataspace of the dataset */ if(FAIL == (space_id = H5Dget_space(dset_id))) - goto done; + goto done; /* Get the rank of this dataspace */ if((sndims = H5Sget_simple_extent_ndims(space_id)) < 0) - goto done; + goto done; ndims = (unsigned)sndims; /* Verify correct axis */ if(axis >= ndims) - goto done; + goto done; /* Get the dimensions sizes of the dataspace */ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0) - goto done; + goto done; /* Adjust the dimension size of the requested dimension, but first record the old dimension size */ old_size = size[axis]; size[axis] += extension; if(size[axis] < old_size) - goto done; + goto done; /* Set the extent of the dataset to the new dimension */ if(H5Dset_extent(dset_id, size) < 0) - goto done; + goto done; /* Get the new dataspace of the dataset */ if(FAIL == (new_space_id = H5Dget_space(dset_id))) @@ -282,51 +139,51 @@ H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, } /* end if */ } /* end for */ if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block)) - goto done; + goto done; /* The # of elemnts in the new extended dataspace */ if((snelmts = H5Sget_select_npoints(new_space_id)) < 0) - goto done; + goto done; nelmts = (hsize_t)snelmts; /* create a memory space */ if(FAIL == (mem_space_id = H5Screate_simple(1, &nelmts, NULL))) - goto done; + goto done; /* Write the data */ if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0) - goto done; + goto done; /* Obtain the dataset's access property list */ if((dapl = H5Dget_access_plist(dset_id)) < 0) - goto done; + goto done; /* Allocate the boundary array */ boundary = (hsize_t *)HDmalloc(ndims * sizeof(hsize_t)); /* Retrieve the append flush property */ if(H5Pget_append_flush(dapl, ndims, boundary, &append_cb, &udata) < 0) - goto done; + goto done; /* No boundary for this axis */ if(boundary[axis] != 0) { - /* Determine whether a boundary is hit or not */ - for(k = start[axis]; k < size[axis]; k++) - if(!((k + 1) % boundary[axis])) { - hit = TRUE; - break; - } - - if(hit) { /* Hit the boundary */ - /* Invoke callback if there is one */ - if(append_cb && append_cb(dset_id, size, udata) < 0) - goto done; - - /* Do a dataset flush */ - if(H5Dflush(dset_id) < 0) - goto done; - } /* end if */ + /* Determine whether a boundary is hit or not */ + for(k = start[axis]; k < size[axis]; k++) + if(!((k + 1) % boundary[axis])) { + hit = TRUE; + break; + } + + if(hit) { /* Hit the boundary */ + /* Invoke callback if there is one */ + if(append_cb && append_cb(dset_id, size, udata) < 0) + goto done; + + /* Do a dataset flush */ + if(H5Dflush(dset_id) < 0) + goto done; + } /* end if */ } /* end if */ /* Indicate success */ @@ -341,22 +198,22 @@ done: /* Close old dataspace */ if(space_id != FAIL && H5Sclose(space_id) < 0) - ret_value = FAIL; + ret_value = FAIL; /* Close new dataspace */ if(new_space_id != FAIL && H5Sclose(new_space_id) < 0) - ret_value = FAIL; + ret_value = FAIL; /* Close memory dataspace */ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0) - ret_value = FAIL; + ret_value = FAIL; /* Close the dataset access property list */ if(dapl != FAIL && H5Pclose(dapl) < 0) - ret_value = FAIL; + ret_value = FAIL; if(boundary) - HDfree(boundary); + HDfree(boundary); return ret_value; } /* H5DOappend() */ diff --git a/hl/src/H5DOpublic.h b/hl/src/H5DOpublic.h index d5c8de4..7f83a7f 100644 --- a/hl/src/H5DOpublic.h +++ b/hl/src/H5DOpublic.h @@ -25,15 +25,6 @@ extern "C" { *------------------------------------------------------------------------- */ -H5_HLDLL herr_t H5DOwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, - const hsize_t *offset, size_t data_size, const void *buf); - -H5_HLDLL herr_t H5DOread_chunk(hid_t dset_id, /*in*/ - hid_t dxpl_id, /*in*/ - const hsize_t *offset, /*in*/ - uint32_t *filters, /*out*/ - void *buf); /*out*/ - H5_HLDLL herr_t H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, hid_t memtype, const void *buf); diff --git a/hl/test/CMakeLists.txt b/hl/test/CMakeLists.txt index 6b3c764..8a059a2 100644 --- a/hl/test/CMakeLists.txt +++ b/hl/test/CMakeLists.txt @@ -47,7 +47,6 @@ HL_ADD_EXE (test_image) HL_ADD_EXE (test_file_image) HL_ADD_EXE (test_table) HL_ADD_EXE (test_ds) -HL_ADD_EXE (test_dset_opt) HL_ADD_EXE (test_ld) HL_ADD_EXE (test_dset_append) diff --git a/hl/test/CMakeTests.cmake b/hl/test/CMakeTests.cmake index e5eb58e..6f57a8c 100644 --- a/hl/test/CMakeTests.cmake +++ b/hl/test/CMakeTests.cmake @@ -90,7 +90,6 @@ add_test ( test_ds8.h5 test_ds9.h5 test_ds10.h5 - test_dectris.h5 test_image1.h5 test_image2.h5 test_image3.h5 @@ -115,7 +114,6 @@ HL_add_test (test_file_image) HL_add_test (test_table) HL_add_test (test_ds) HL_add_test (test_packet) -HL_add_test (test_dset_opt) HL_add_test (test_ld) HL_add_test (test_dset_append) diff --git a/hl/test/Makefile.am b/hl/test/Makefile.am index e16550f..35e680c 100644 --- a/hl/test/Makefile.am +++ b/hl/test/Makefile.am @@ -26,7 +26,7 @@ LDADD=$(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) # Test programs. These are our main targets. They should be listed in the # order to be executed, generally most specific tests to least specific tests. -TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet test_dset_opt \ +TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet \ test_ld test_dset_append check_PROGRAMS=$(TEST_PROG) @@ -45,8 +45,7 @@ endif CHECK_CLEANFILES+=combine_tables[1-2].h5 test_ds[1-9].h5 test_ds10.h5 \ test_image[1-3].h5 file_img[1-2].h5 test_lite[1-4].h5 test_table.h5 \ test_packet_table.h5 test_packet_compress.h5 test_detach.h5 \ - test_packet_table_vlen.h5 testfl_packet_table_vlen.h5 \ - test_dectris.h5 test_append.h5 + test_packet_table_vlen.h5 testfl_packet_table_vlen.h5 test_append.h5 # Sources for test_packet executable test_packet_SOURCES=test_packet.c test_packet_vlen.c diff --git a/hl/test/dectris_hl_perf.c b/hl/test/dectris_hl_perf.c deleted file mode 100644 index 13cfac8..0000000 --- a/hl/test/dectris_hl_perf.c +++ /dev/null @@ -1,691 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * 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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * This test is for the DECTRIS project to the H5DOwrite_chunk function - * - */ - -#include "hdf5_hl.h" - -#ifdef H5_HAVE_FILTER_DEFLATE -#include - -#if !defined(WIN32) && !defined(__MINGW32__) - -#include - -#ifdef H5_STDC_HEADERS -# include -# include -# include -# include -#endif - -#ifdef H5_HAVE_UNISTD_H -# include -# include -#endif - -#ifdef H5_HAVE_SYS_STAT_H -# include -#endif - -#if defined(H5_TIME_WITH_SYS_TIME) -# include -# include -#elif defined(H5_HAVE_SYS_TIME_H) -# include -#else -# include -#endif - -const char *FILENAME[] = { - "dectris_perf", - "unix.raw", - NULL -}; - -/* - * Print the current location on the standard output stream. - */ -#define FUNC __func__ -#define AT() printf (" at %s:%d in %s()...\n", \ - __FILE__, __LINE__, FUNC); -#define H5_FAILED() {puts("*FAILED*");fflush(stdout);} -#define TEST_ERROR {H5_FAILED(); AT(); goto error;} -#define TESTING(WHAT) {printf("Testing %-62s",WHAT); fflush(stdout);} -#define PASSED() {puts(" PASSED");fflush(stdout);} - -#define DIRECT_UNCOMPRESSED_DSET "direct_uncompressed_dset" -#define DIRECT_COMPRESSED_DSET "direct_compressed_dset" -#define REG_COMPRESSED_DSET "reg_compressed_dset" -#define REG_NO_COMPRESS_DSET "reg_no_compress_dset" -#define RANK 3 -#define NX 100 -#define NY 1000 -#define NZ 250 -#define CHUNK_NX 1 -#define CHUNK_NY 1000 -#define CHUNK_NZ 250 - -#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s))*1.001)+12) -char filename[1024]; -unsigned int *outbuf[NX]; -size_t data_size[NX]; -double total_size = 0.0; -unsigned int *direct_buf[NX]; -double MB = 1048576.0; - -/*-------------------------------------------------- - * Function to report IO rate - *-------------------------------------------------- - */ -void reportTime(struct timeval start, double mbytes) -{ - struct timeval timeval_stop,timeval_diff; - - /*end timing*/ - gettimeofday(&timeval_stop,NULL); - - /* Calculate the elapsed gettimeofday time */ - timeval_diff.tv_usec=timeval_stop.tv_usec-start.tv_usec; - timeval_diff.tv_sec=timeval_stop.tv_sec-start.tv_sec; - - if(timeval_diff.tv_usec<0) { - timeval_diff.tv_usec+=1000000; - timeval_diff.tv_sec--; - } /* end if */ - -/*printf("mbytes=%lf, sec=%lf, usec=%lf\n", mbytes, (double)timeval_diff.tv_sec, (double)timeval_diff.tv_usec);*/ - printf("MBytes/second: %lf\n", (double)mbytes/((double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0))); -} - -/*-------------------------------------------------- - * Create file, datasets, and initialize data - *-------------------------------------------------- - */ -int create_file(hid_t fapl_id) -{ - hid_t file; /* handles */ - hid_t fapl; - hid_t cparms; - hid_t dataspace, dataset; - hsize_t dims[RANK] = {NX, NY, NZ}; - hsize_t chunk_dims[RANK] ={CHUNK_NX, CHUNK_NY, CHUNK_NZ}; - unsigned int aggression = 9; /* Compression aggression setting */ - int ret; - int i, j, n; - - int flag; - int unix_file; - - unsigned int *p; - size_t buf_size = CHUNK_NY*CHUNK_NZ*sizeof(unsigned int); - - const Bytef *z_src; - Bytef *z_dst; /*destination buffer */ - uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); - uLong z_src_nbytes = (uLong)buf_size; - - TESTING("Create a file and dataset"); - - /* - * Create the data space with unlimited dimensions. - */ - if((dataspace = H5Screate_simple(RANK, dims, NULL)) < 0) - TEST_ERROR; - - /* - * Create a new file. If file exists its contents will be overwritten. - */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) - TEST_ERROR; - - /* - * Modify dataset creation properties, i.e. enable chunking and compression - */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - TEST_ERROR; - - if(H5Pset_chunk( cparms, RANK, chunk_dims) < 0) - TEST_ERROR; - - /* - * Create a new dataset within the file using cparms - * creation properties. - */ - if((dataset = H5Dcreate2(file, DIRECT_UNCOMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - TEST_ERROR; - - if(H5Dclose(dataset) < 0) - TEST_ERROR; - - if((dataset = H5Dcreate2(file, REG_NO_COMPRESS_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - TEST_ERROR; - - if(H5Dclose(dataset) < 0) - TEST_ERROR; - - /* Set compression */ - if(H5Pset_deflate( cparms, aggression) < 0) - TEST_ERROR; - - if((dataset = H5Dcreate2(file, DIRECT_COMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - TEST_ERROR; - - if(H5Dclose(dataset) < 0) - TEST_ERROR; - - - if((dataset = H5Dcreate2(file, REG_COMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - TEST_ERROR; - - if(H5Dclose(dataset) < 0) - TEST_ERROR; - - if(H5Fclose(file) < 0) - TEST_ERROR; - - if(H5Sclose(dataspace) < 0) - TEST_ERROR; - - if(H5Pclose(cparms) < 0) - TEST_ERROR; - - /* create a unix file*/ - flag = O_CREAT|O_TRUNC|O_WRONLY; - - if ((unix_file=open(FILENAME[1],flag,S_IRWXU))== -1) - TEST_ERROR; - - if (close(unix_file) < 0) - { - printf(" unable to close the file\n"); - TEST_ERROR; - } - - - /* Initialize data for chunks */ - for(i = 0; i < NX; i++) { - p = direct_buf[i] = (unsigned int*)malloc(CHUNK_NY*CHUNK_NZ*sizeof(unsigned int)); - - for(j=0; j < CHUNK_NY*CHUNK_NZ; j++, p++) - *p = rand() % 65000; - - z_src = (const Bytef*)direct_buf[i]; - - z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); - /* Allocate output (compressed) buffer */ - outbuf[i] = (unsigned int*)malloc((size_t)z_dst_nbytes); - z_dst = (Bytef *)outbuf[i]; - - /* Perform compression from the source to the destination buffer */ - ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); - - data_size[i] = (size_t)z_dst_nbytes; - total_size += data_size[i]; - - /* Check for various zlib errors */ - if(Z_BUF_ERROR == ret) { - fprintf(stderr, "overflow"); - TEST_ERROR; - } else if(Z_MEM_ERROR == ret) { - fprintf(stderr, "deflate memory error"); - TEST_ERROR; - } else if(Z_OK != ret) { - fprintf(stderr, "other deflate error"); - TEST_ERROR; - } - } - - - PASSED(); - -error: - H5E_BEGIN_TRY { - H5Dclose(dataset); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Fclose(file); - } H5E_END_TRY; - return 1; -} - -/*-------------------------------------------------- - * Benchmark the performance of the new function - * with precompressed data. - *-------------------------------------------------- - */ -int -test_direct_write_uncompressed_data(hid_t fapl_id) -{ - hid_t file; /* handles */ - hid_t dataspace, dataset; - hid_t dxpl; - herr_t status; - int i; - - unsigned filter_mask = 0; - hsize_t offset[RANK] = {0, 0, 0}; - - struct timeval timeval_start; - - TESTING("H5DOwrite_chunk for uncompressed data"); - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - TEST_ERROR; - - /* Start the timer */ - gettimeofday(&timeval_start,NULL); - - /* Reopen the file and dataset */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) - TEST_ERROR; - - if((dataset = H5Dopen2(file, DIRECT_UNCOMPRESSED_DSET, H5P_DEFAULT)) < 0) - TEST_ERROR; - - - /* Write the compressed chunk data repeatedly to cover all the chunks in the - * dataset, using the direct writing function. */ - for(i=0; i -#include -#include "h5hltest.h" -#include "H5DOpublic.h" -#include - -#if defined(H5_HAVE_ZLIB_H) && !defined(H5_ZLIB_HEADER) -# define H5_ZLIB_HEADER "zlib.h" -#endif -#if defined(H5_ZLIB_HEADER) -# include H5_ZLIB_HEADER /* "zlib.h" */ -#endif - -#define FILE_NAME "test_dectris.h5" - -/* Datasets for Direct Write tests */ -#define DATASETNAME1 "direct_write" -#define DATASETNAME2 "skip_one_filter" -#define DATASETNAME3 "skip_two_filters" -#define DATASETNAME4 "data_conv" -#define DATASETNAME5 "contiguous_dset" -#define DATASETNAME6 "invalid_argue" -#define DATASETNAME7 "overwrite_chunk" -/* Datasets for Direct Read tests */ -#define DATASETNAME8 "disabled_chunk_cache" -#define DATASETNAME9 "flush_chunk_cache" -#define DATASETNAME10 "read_w_valid_cache" -#define DATASETNAME11 "unallocated_chunk" -#define DATASETNAME12 "unfiltered_data" - -#define RANK 2 -#define NX 16 -#define NY 16 -#define CHUNK_NX 4 -#define CHUNK_NY 4 - -#define DEFLATE_SIZE_ADJUST(s) (HDceil(((double)(s))*H5_DOUBLE(1.001))+H5_DOUBLE(12.0)) - -/* Temporary filter IDs used for testing */ -#define H5Z_FILTER_BOGUS1 305 -#define H5Z_FILTER_BOGUS2 306 -#define ADD_ON 7 -#define FACTOR 3 - -/* Constants for the overwrite test */ -#define OVERWRITE_NDIMS 3 -#define OVERWRITE_CHUNK_NX 3 -#define OVERWRITE_CHUNK_2NX 6 -#define OVERWRITE_CHUNK_NY 2 -#define OVERWRITE_VALUE 42 - -/* Defines used in test_single_chunk_latest() */ -#define FILE "single_latest.h5" -#define DATASET "dataset" -#define DIM0 4 -#define DIM1 32 -#define CHUNK0 DIM0 -#define CHUNK1 DIM1 - -/* Local prototypes for filter functions */ -static size_t filter_bogus1(unsigned int flags, size_t cd_nelmts, - const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf); -static size_t filter_bogus2(unsigned int flags, size_t cd_nelmts, - const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf); - -/* This message derives from H5Z */ -const H5Z_class2_t H5Z_BOGUS1[1] = {{ - H5Z_CLASS_T_VERS, /* H5Z_class_t version */ - H5Z_FILTER_BOGUS1, /* Filter id number */ - 1, 1, /* Encoding and decoding enabled */ - "bogus1", /* Filter name for debugging */ - NULL, /* The "can apply" callback */ - NULL, /* The "set local" callback */ - filter_bogus1, /* The actual filter function */ -}}; - -const H5Z_class2_t H5Z_BOGUS2[1] = {{ - H5Z_CLASS_T_VERS, /* H5Z_class_t version */ - H5Z_FILTER_BOGUS2, /* Filter id number */ - 1, 1, /* Encoding and decoding enabled */ - "bogus2", /* Filter name for debugging */ - NULL, /* The "can apply" callback */ - NULL, /* The "set local" callback */ - filter_bogus2, /* The actual filter function */ -}}; - -/*------------------------------------------------------------------------- - * Function: test_direct_chunk_write - * - * Purpose: Test the basic functionality of H5DOwrite_chunk - * - * Return: Success: 0 - * Failure: 1 - * - * Programmer: Raymond Lu - * 30 November 2012 - * - *------------------------------------------------------------------------- - */ -#ifdef H5_HAVE_FILTER_DEFLATE -static int -test_direct_chunk_write (hid_t file) -{ - hid_t dataspace = -1, dataset = -1; - hid_t mem_space = -1; - hid_t cparms = -1, dxpl = -1; - hsize_t dims[2] = {NX, NY}; - hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; - hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; - herr_t status; - int ret; - int data[NX][NY]; - int i, j, n; - - unsigned filter_mask = 0; - int direct_buf[CHUNK_NX][CHUNK_NY]; - int check_chunk[CHUNK_NX][CHUNK_NY]; - hsize_t offset[2] = {0, 0}; - size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); - - const Bytef *z_src = (const Bytef*)(direct_buf); - Bytef *z_dst = NULL; /*destination buffer */ - uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); - uLong z_src_nbytes = (uLong)buf_size; - int aggression = 9; /* Compression aggression setting */ - void *outbuf = NULL; /* Pointer to new buffer */ - - hsize_t start[2]; /* Start of hyperslab */ - hsize_t stride[2]; /* Stride of hyperslab */ - hsize_t count[2]; /* Block count */ - hsize_t block[2]; /* Block sizes */ - - TESTING("basic functionality of H5DOwrite_chunk"); - - /* - * Create the data space with unlimited dimensions. - */ - if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) - goto error; - - if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) - goto error; - - /* - * Modify dataset creation properties, i.e. enable chunking and compression - */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - goto error; - - if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) - goto error; - - if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) - goto error; - - /* - * Create a new dataset within the file using cparms - * creation properties. - */ - if((dataset = H5Dcreate2(file, DATASETNAME1, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - goto error; - - /* Initialize the dataset */ - for(i = n = 0; i < NX; i++) - for(j = 0; j < NY; j++) - data[i][j] = n++; - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto error; - - /* - * Write the data for the dataset. It should stay in the chunk cache. - * It will be evicted from the cache by the H5DOwrite_chunk calls. - */ - if((status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, - dxpl, data)) < 0) - goto error; - - /* Initialize data for one chunk */ - for(i = n = 0; i < CHUNK_NX; i++) - for(j = 0; j < CHUNK_NY; j++) - direct_buf[i][j] = n++; - - /* Allocate output (compressed) buffer */ - outbuf = HDmalloc(z_dst_nbytes); - z_dst = (Bytef *)outbuf; - - /* Perform compression from the source to the destination buffer */ - ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); - - /* Check for various zlib errors */ - if(Z_BUF_ERROR == ret) { - HDfprintf(stderr, "overflow"); - goto error; - } else if(Z_MEM_ERROR == ret) { - HDfprintf(stderr, "deflate memory error"); - goto error; - } else if(Z_OK != ret) { - HDfprintf(stderr, "other deflate error"); - goto error; - } - - /* Write the compressed chunk data repeatedly to cover all the chunks in the - * dataset, using the direct writing function. */ - for(i=0; i0) { - *int_ptr++ -= (int)ADD_ON; - buf_left -= (ssize_t)sizeof(int); - } /* end while */ - } /* end if */ - else { /* write */ - /* Add the "add on" value to all the data values */ - while(buf_left>0) { - *int_ptr++ += (int)ADD_ON; - buf_left -= (ssize_t)sizeof(int); - } /* end while */ - } /* end else */ - - return nbytes; -} /* filter_bogus1() */ - -/*------------------------------------------------------------------------- - * Function: filter_bogus2 - * - * Purpose: A bogus filter that multiplies the original value by FACTOR. - * - * Return: Success: Data chunk size - * - * Programmer: Raymond Lu - * 30 November 2012 - *------------------------------------------------------------------------- - */ -static size_t -filter_bogus2(unsigned int flags, size_t H5_ATTR_UNUSED cd_nelmts, - const unsigned int H5_ATTR_UNUSED *cd_values, size_t nbytes, - size_t *buf_size, void **buf) -{ - int *int_ptr=(int *)*buf; /* Pointer to the data values */ - ssize_t buf_left=(ssize_t)*buf_size; /* Amount of data buffer left to process */ - - if(flags & H5Z_FLAG_REVERSE) { /* read */ - /* Substract the "add on" value to all the data values */ - while(buf_left>0) { - *int_ptr++ /= (int)FACTOR; - buf_left -= (ssize_t)sizeof(int); - } /* end while */ - } /* end if */ - else { /* write */ - /* Add the "add on" value to all the data values */ - while(buf_left>0) { - *int_ptr++ *= (int)FACTOR; - buf_left -= (ssize_t)sizeof(int); - } /* end while */ - } /* end else */ - - return nbytes; -} /* filter_bogus2() */ - -/*------------------------------------------------------------------------- - * Function: test_skip_compress_write2 - * - * Purpose: Test skipping compression filter when there are three filters - * for the dataset - * - * Return: Success: 0 - * Failure: 1 - * - * Programmer: Raymond Lu - * 30 November 2012 - * - *------------------------------------------------------------------------- - */ -static int -test_skip_compress_write2(hid_t file) -{ - hid_t dataspace = -1, dataset = -1; - hid_t mem_space = -1; - hid_t cparms = -1, dxpl = -1; - hsize_t dims[2] = {NX, NY}; - hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; - hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; - herr_t status; - int i, j, n; - - unsigned filter_mask = 0; /* orig filter mask */ - int origin_direct_buf[CHUNK_NX][CHUNK_NY]; - int direct_buf[CHUNK_NX][CHUNK_NY]; - int check_chunk[CHUNK_NX][CHUNK_NY]; - hsize_t offset[2] = {0, 0}; - size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); - int aggression = 9; /* Compression aggression setting */ - - unsigned read_filter_mask = 0; /* filter mask after direct read */ - int read_direct_buf[CHUNK_NX][CHUNK_NY]; - hsize_t read_buf_size = 0; /* buf size */ - - hsize_t start[2]; /* Start of hyperslab */ - hsize_t stride[2]; /* Stride of hyperslab */ - hsize_t count[2]; /* Block count */ - hsize_t block[2]; /* Block sizes */ - - TESTING("skipping compression filters but keep two other filters"); - - /* - * Create the data space with unlimited dimensions. - */ - if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) - goto error; - - if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) - goto error; - - /* - * Modify dataset creation properties, i.e. enable chunking and compression. - * The order of filters is bogus 1 + deflate + bogus 2. - */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - goto error; - - if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) - goto error; - - /* Register and enable first bogus filter */ - if(H5Zregister (H5Z_BOGUS1) < 0) - goto error; - - if(H5Pset_filter(cparms, H5Z_FILTER_BOGUS1, 0, (size_t)0, NULL) < 0) - goto error; - - /* Enable compression filter */ - if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) - goto error; - - /* Register and enable second bogus filter */ - if(H5Zregister (H5Z_BOGUS2) < 0) - goto error; - - if(H5Pset_filter(cparms, H5Z_FILTER_BOGUS2, 0, (size_t)0, NULL) < 0) - goto error; - - /* - * Create a new dataset within the file using cparms - * creation properties. - */ - if((dataset = H5Dcreate2(file, DATASETNAME3, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - goto error; - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto error; - - /* Initialize data for one chunk. Apply operations of two bogus filters to the chunk */ - for(i = n = 0; i < CHUNK_NX; i++) - for(j = 0; j < CHUNK_NY; j++) { - origin_direct_buf[i][j] = n++; - direct_buf[i][j] = (origin_direct_buf[i][j] + ADD_ON) * FACTOR; - } - - /* write the uncompressed chunk data repeatedly to dataset, using the direct writing function. - * Indicate skipping the compression filter but keep the other two bogus filters */ - offset[0] = CHUNK_NX; - offset[1] = CHUNK_NY; - - /* compression filter is the middle one to be skipped */ - filter_mask = 0x00000002; - - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) < 0) - goto error; - - if(H5Fflush(dataset, H5F_SCOPE_LOCAL) < 0) - goto error; - - if(H5Dclose(dataset) < 0) - goto error; - - if((dataset = H5Dopen2(file, DATASETNAME3, H5P_DEFAULT)) < 0) - goto error; - - /* - * Select hyperslab for one chunk in the file - */ - start[0] = CHUNK_NX; start[1] = CHUNK_NY; - stride[0] = 1; stride[1] = 1; - count[0] = 1; count[1] = 1; - block[0] = CHUNK_NX; block[1] = CHUNK_NY; - if((status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, stride, count, block)) < 0) - goto error; - - /* Read the chunk back */ - if((status = H5Dread(dataset, H5T_NATIVE_INT, mem_space, dataspace, H5P_DEFAULT, check_chunk)) < 0) - goto error; - - /* Check that the values read are the same as the values written */ - for(i = 0; i < CHUNK_NX; i++) { - for(j = 0; j < CHUNK_NY; j++) { - if(origin_direct_buf[i][j] != check_chunk[i][j]) { - HDprintf(" 1. Read different values than written."); - HDprintf(" At index %d,%d\n", i, j); - HDprintf(" origin_direct_buf=%d, check_chunk=%d\n", origin_direct_buf[i][j], check_chunk[i][j]); - goto error; - } - } - } - - /* Query chunk storage size */ - if((status = H5Dget_chunk_storage_size(dataset, offset, &read_buf_size)) < 0) - goto error; - if(read_buf_size != buf_size) - goto error; - - /* Read the raw chunk back */ - HDmemset(&read_direct_buf, 0, sizeof(read_direct_buf)); - if((status = H5DOread_chunk(dataset, H5P_DEFAULT, offset, &read_filter_mask, read_direct_buf)) < 0) - goto error; - if(read_filter_mask != filter_mask) - goto error; - - /* Check that the direct chunk read is the same as the chunk written */ - for(i = 0; i < CHUNK_NX; i++) { - for(j = 0; j < CHUNK_NY; j++) { - if(direct_buf[i][j] != read_direct_buf[i][j]) { - HDprintf(" 1. Read different values than written."); - HDprintf(" At index %d,%d\n", i, j); - HDprintf(" direct_buf=%d, read_direct_buf=%d\n", direct_buf[i][j], read_direct_buf[i][j]); - goto error; - } - } - } - - /* - * Close/release resources. - */ - H5Dclose(dataset); - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - - PASSED(); - return 0; - -error: - H5E_BEGIN_TRY { - H5Dclose(dataset); - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - } H5E_END_TRY; - - H5_FAILED(); - return 1; -} /* test_skip_compress_write2() */ - -/*------------------------------------------------------------------------- - * Function: test_data_conv - * - * Purpose: Test data conversion - * - * Return: Success: 0 - * Failure: 1 - * - * Programmer: Raymond Lu - * 30 November 2012 - * - *------------------------------------------------------------------------- - */ -static int -test_data_conv(hid_t file) -{ - typedef struct { - int a, b, c[4], d, e; - } src_type_t; - typedef struct { - int a, c[4], e; - } dst_type_t; - - hid_t dataspace = -1, dataset = -1; - hid_t mem_space = -1; - hid_t cparms = -1, dxpl = -1; - hsize_t dims[2] = {NX, NY}; - hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; - hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; - herr_t status; - int i, j, n; - const hsize_t four = 4; - hid_t st=-1, dt=-1; - hid_t array_dt; - - unsigned filter_mask = 0; - src_type_t direct_buf[CHUNK_NX][CHUNK_NY]; - dst_type_t check_chunk[CHUNK_NX][CHUNK_NY]; - src_type_t read_chunk[CHUNK_NX][CHUNK_NY]; /* For H5DOread_chunk */ - - hsize_t offset[2] = {0, 0}; - size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(src_type_t); - - hsize_t start[2]; /* Start of hyperslab */ - hsize_t stride[2]; /* Stride of hyperslab */ - hsize_t count[2]; /* Block count */ - hsize_t block[2]; /* Block sizes */ - - TESTING("data conversion for H5DOwrite_chunk/H5DOread_chunk"); - - /* - * Create the data space with unlimited dimensions. - */ - if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) - goto error; - - if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) - goto error; - - /* - * Modify dataset creation properties, i.e. enable chunking - */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - goto error; - - if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) - goto error; - - /* Build hdf5 datatypes */ - array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, &four); - if((st = H5Tcreate(H5T_COMPOUND, sizeof(src_type_t))) < 0 || - H5Tinsert(st, "a", HOFFSET(src_type_t, a), H5T_NATIVE_INT) < 0 || - H5Tinsert(st, "b", HOFFSET(src_type_t, b), H5T_NATIVE_INT) < 0 || - H5Tinsert(st, "c", HOFFSET(src_type_t, c), array_dt) < 0 || - H5Tinsert(st, "d", HOFFSET(src_type_t, d), H5T_NATIVE_INT) < 0 || - H5Tinsert(st, "e", HOFFSET(src_type_t, e), H5T_NATIVE_INT) < 0) - goto error; - - if(H5Tclose(array_dt) < 0) - goto error; - - array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, &four); - if((dt = H5Tcreate(H5T_COMPOUND, sizeof(dst_type_t))) < 0 || - H5Tinsert(dt, "a", HOFFSET(dst_type_t, a), H5T_NATIVE_INT) < 0 || - H5Tinsert(dt, "c", HOFFSET(dst_type_t, c), array_dt) < 0 || - H5Tinsert(dt, "e", HOFFSET(dst_type_t, e), H5T_NATIVE_INT) < 0) - goto error; - - if(H5Tclose(array_dt) < 0) - goto error; - - /* - * Create a new dataset within the file using cparms - * creation properties. - */ - if((dataset = H5Dcreate2(file, DATASETNAME4, st, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - goto error; - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto error; - - /* Initialize data for one chunk */ - for(i = n = 0; i < CHUNK_NX; i++) { - for(j = 0; j < CHUNK_NY; j++) { - (direct_buf[i][j]).a = i*j+0; - (direct_buf[i][j]).b = i*j+1; - (direct_buf[i][j]).c[0] = i*j+2; - (direct_buf[i][j]).c[1] = i*j+3; - (direct_buf[i][j]).c[2] = i*j+4; - (direct_buf[i][j]).c[3] = i*j+5; - (direct_buf[i][j]).d = i*j+6; - (direct_buf[i][j]).e = i*j+7; - } - } - - /* write the chunk data to dataset, using the direct writing function. - * There should be no data conversion involved. */ - offset[0] = CHUNK_NX; - offset[1] = CHUNK_NY; - - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) < 0) - goto error; - - if(H5Fflush(dataset, H5F_SCOPE_LOCAL) < 0) - goto error; - - if(H5Dclose(dataset) < 0) - goto error; - - if((dataset = H5Dopen2(file, DATASETNAME4, H5P_DEFAULT)) < 0) - goto error; - - /* Use H5DOread_chunk() to read the uncompressed data */ - if((status = H5DOread_chunk(dataset, dxpl, offset, &filter_mask, read_chunk)) < 0) - goto error; - - /* Check that the values read are the same as the values written */ - for(i = 0; i < CHUNK_NX; i++) { - for(j = 0; j < CHUNK_NY; j++) { - if ((direct_buf[i][j]).a != (read_chunk[i][j]).a || - (direct_buf[i][j]).b != (read_chunk[i][j]).b || - (direct_buf[i][j]).c[0] != (read_chunk[i][j]).c[0] || - (direct_buf[i][j]).c[1] != (read_chunk[i][j]).c[1] || - (direct_buf[i][j]).c[2] != (read_chunk[i][j]).c[2] || - (direct_buf[i][j]).c[3] != (read_chunk[i][j]).c[3] || - (direct_buf[i][j]).d != (read_chunk[i][j]).d || - (direct_buf[i][j]).e != (read_chunk[i][j]).e) { - HDprintf(" 1. Read different values than written."); - HDprintf(" At index %d,%d\n", i, j); - HDprintf(" src={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", - (direct_buf[i][j]).a, (direct_buf[i][j]).b, (direct_buf[i][j]).c[0], (direct_buf[i][j]).c[1], - (direct_buf[i][j]).c[2], (direct_buf[i][j]).c[3], (direct_buf[i][j]).d, (direct_buf[i][j]).e); - HDprintf(" dst={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", - (read_chunk[i][j]).a, (read_chunk[i][j]).b, (read_chunk[i][j]).c[0], (read_chunk[i][j]).c[1], - (read_chunk[i][j]).c[2], (read_chunk[i][j]).c[3], (read_chunk[i][j]).d, (read_chunk[i][j]).e); - - goto error; - } - } - } - - /* - * Select hyperslab for the chunk just written in the file - */ - start[0] = CHUNK_NX; start[1] = CHUNK_NY; - stride[0] = 1; stride[1] = 1; - count[0] = 1; count[1] = 1; - block[0] = CHUNK_NX; block[1] = CHUNK_NY; - if((status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, stride, count, block)) < 0) - goto error; - - /* Read the chunk back. Data should be converted */ - if((status = H5Dread(dataset, dt, mem_space, dataspace, H5P_DEFAULT, check_chunk)) < 0) - goto error; - - /* Check that the values read are the same as the values written */ - for(i = 0; i < CHUNK_NX; i++) { - for(j = 0; j < CHUNK_NY; j++) { - if ((direct_buf[i][j]).a != (check_chunk[i][j]).a || - (direct_buf[i][j]).c[0] != (check_chunk[i][j]).c[0] || - (direct_buf[i][j]).c[1] != (check_chunk[i][j]).c[1] || - (direct_buf[i][j]).c[2] != (check_chunk[i][j]).c[2] || - (direct_buf[i][j]).c[3] != (check_chunk[i][j]).c[3] || - (direct_buf[i][j]).e != (check_chunk[i][j]).e) { - HDprintf(" 1. Read different values than written."); - HDprintf(" At index %d,%d\n", i, j); - HDprintf(" src={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", - (direct_buf[i][j]).a, (direct_buf[i][j]).b, (direct_buf[i][j]).c[0], (direct_buf[i][j]).c[1], - (direct_buf[i][j]).c[2], (direct_buf[i][j]).c[3], (direct_buf[i][j]).d, (direct_buf[i][j]).e); - HDprintf(" dst={a=%d, c=[%d,%d,%d,%d], e=%d\n", - (check_chunk[i][j]).a, (check_chunk[i][j]).c[0], (check_chunk[i][j]).c[1], (check_chunk[i][j]).c[2], - (check_chunk[i][j]).c[3], (check_chunk[i][j]).e); - - goto error; - } - } - } - - /* - * Close/release resources. - */ - H5Dclose(dataset); - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - H5Tclose(st); - H5Tclose(dt); - - PASSED(); - return 0; - -error: - H5E_BEGIN_TRY { - H5Dclose(dataset); - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - H5Tclose(st); - H5Tclose(dt); - } H5E_END_TRY; - - H5_FAILED(); - return 1; -} /* test_data_conv() */ - -/*------------------------------------------------------------------------- - * Function: test_invalid_parameters - * - * Purpose: Test invalid parameters for H5DOwrite_chunk and H5DOread_chunk - * - * Return: Success: 0 - * Failure: 1 - * - * Programmer: Raymond Lu - * 30 November 2012 - * - *------------------------------------------------------------------------- - */ -static int -test_invalid_parameters(hid_t file) -{ - hid_t dataspace = -1, dataset = -1; - hid_t mem_space = -1; - hid_t cparms = -1, dxpl = -1; - hsize_t dims[2] = {NX, NY}; - hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; - herr_t status; - int i, j, n; - - unsigned filter_mask = 0; - int direct_buf[CHUNK_NX][CHUNK_NY]; - hsize_t offset[2] = {0, 0}; - size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); - int aggression = 9; /* Compression aggression setting */ - - hsize_t chunk_nbytes; /* Chunk size */ - - TESTING("invalid parameters for H5DOwrite_chunk/H5DOread_chunk"); - - /* - * Create the data space with unlimited dimensions. - */ - if((dataspace = H5Screate_simple(RANK, dims, NULL)) < 0) - goto error; - - if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) - goto error; - - /* - * Modify dataset creation properties - */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - goto error; - - /* - * Create a new contiguous dataset to verify H5DOwrite_chunk/H5DOread_chunk doesn't work - */ - if((dataset = H5Dcreate2(file, DATASETNAME5, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - goto error; - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto error; - - /* Initialize data for one chunk */ - for(i = n = 0; i < CHUNK_NX; i++) - for(j = 0; j < CHUNK_NY; j++) { - direct_buf[i][j] = n++; - } - - /* Try to write the chunk data to contiguous dataset. It should fail */ - offset[0] = CHUNK_NX; - offset[1] = CHUNK_NY; - - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Try to get chunk size for a contiguous dataset. It should fail */ - H5E_BEGIN_TRY { - if((status = H5Dget_chunk_storage_size(dataset, offset, &chunk_nbytes)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Try to H5DOread_chunk from the contiguous dataset. It should fail */ - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - if(H5Dclose(dataset) < 0) - goto error; - - - /* Create a chunked dataset with compression filter */ - if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) - goto error; - - if((status = H5Pset_deflate( cparms, (unsigned ) aggression)) < 0) - goto error; - - /* - * Create a new dataset within the file using cparms - * creation properties. - */ - if((dataset = H5Dcreate2(file, DATASETNAME6, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, H5P_DEFAULT)) < 0) - goto error; - - /* Check invalid dataset ID for H5DOwrite_chunk and H5DOread_chunk */ - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk((hid_t)-1, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk((hid_t)-1, dxpl, offset, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check invalid DXPL ID for H5DOwrite_chunk and H5DOread_chunk */ - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, (hid_t)-1, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, (hid_t)-1, offset, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check invalid OFFSET for H5DOwrite_chunk and H5DOread_chunk */ - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, NULL, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, dxpl, NULL, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check when OFFSET is out of dataset range for H5DOwrite_chunk and H5DOread_chunk */ - offset[0] = NX + 1; - offset[1] = NY; - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check when OFFSET is not on chunk boundary for H5DOwrite_chunk and H5DOread_chunk */ - offset[0] = CHUNK_NX; - offset[1] = CHUNK_NY + 1; - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check invalid buffer size for H5DOwrite_chunk only */ - offset[0] = CHUNK_NX; - offset[1] = CHUNK_NY; - buf_size = 0; - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) - goto error; - } H5E_END_TRY; - - /* Check invalid data buffer for H5DOwrite_chunk and H5DOread_chunk */ - buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); - H5E_BEGIN_TRY { - if((status = H5DOwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, NULL)) != FAIL) - goto error; - } H5E_END_TRY; - - H5E_BEGIN_TRY { - if((status = H5DOread_chunk(dataset, dxpl, offset, &filter_mask, NULL)) != FAIL) - goto error; - } H5E_END_TRY; - - if(H5Dclose(dataset) < 0) - goto error; - - /* - * Close/release resources. - */ - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - - PASSED(); - return 0; - -error: - H5E_BEGIN_TRY { - H5Dclose(dataset); - H5Sclose(mem_space); - H5Sclose(dataspace); - H5Pclose(cparms); - H5Pclose(dxpl); - } H5E_END_TRY; - - H5_FAILED(); - return 1; -} /* test_invalid_parameters() */ - -/*------------------------------------------------------------------------- - * Function: test_direct_chunk_read_no_cache - * - * Purpose: Test the basic functionality of H5DOread_chunk with the - * chunk cache diabled. - * - * Return: Success: 0 - * Failure: 1 - * - * Programmer: Matthew Strong (GE Healthcare) - * 14 February 2016 - * - *------------------------------------------------------------------------- - */ -#ifdef H5_HAVE_FILTER_DEFLATE -static int -test_direct_chunk_read_no_cache (hid_t file) -{ - hid_t dataspace = -1, dataset = -1; - hid_t mem_space = -1; - hid_t cparms = -1, dxpl = -1, dapl = -1; - hsize_t dims[2] = {NX, NY}; - hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; - hsize_t chunk_dims[2] = {CHUNK_NX, CHUNK_NY}; - herr_t status; /* status from H5 function calls */ - int ret; /* deflate return status */ - int data[NX][NY]; - int i, j, k, l, n; /* local index variables */ - - unsigned filter_mask = 0; /* filter mask returned from H5DOread_chunk */ - int direct_buf[CHUNK_NX][CHUNK_NY]; /* chunk read with H5DOread and manually decompressed */ - int check_chunk[CHUNK_NX][CHUNK_NY]; /* chunk read with H5Dread */ - hsize_t offset[2]; /* chunk offset used for H5DOread_chunk */ - size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); - - Bytef *z_src = NULL; /* source buffer */ - uLongf z_src_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); - Bytef *z_dst = (Bytef*)(direct_buf); - uLong z_dst_nbytes = (uLong)buf_size; - int aggression = 9; /* Compression aggression setting */ - void *outbuf = NULL; /* Pointer to new buffer */ - - hsize_t start[2]; /* Start of hyperslab */ - hsize_t stride[2]; /* Stride of hyperslab */ - hsize_t count[2]; /* Block count */ - hsize_t block[2]; /* Block sizes */ - - TESTING("basic functionality of H5DOread_chunk (chunk cache disabled)"); - - /* Create the data space with unlimited dimensions. */ - if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) - goto error; - if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) - goto error; - - /* Modify dataset creation properties, i.e. enable chunking and compression */ - if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) - goto error; - if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) - goto error; - if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) - goto error; - if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) - goto error; - - /* Disable chunk cache by setting number of slots to 0 */ - if((status = H5Pset_chunk_cache(dapl, 0, H5D_CHUNK_CACHE_NBYTES_DEFAULT, H5D_CHUNK_CACHE_W0_DEFAULT)) < 0) - goto error; - - /* Create a new dataset within the file using cparms creation properties. */ - if((dataset = H5Dcreate2(file, DATASETNAME8, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, - cparms, dapl)) < 0) - goto error; - - /* Initialize the dataset */ - for(i = n = 0; i < NX; i++) - for(j = 0; j < NY; j++) - data[i][j] = n++; - - if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) - goto error; - - /* Write the data for the dataset. - * Data will skip chunk cache and go directly to disk. */ - if((status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, - dxpl, data)) < 0) - goto error; - - /* Allocate output (compressed) buffer */ - outbuf = HDmalloc(z_src_nbytes); - z_src = (Bytef *)outbuf; - - /* For each chunk in the dataset, compare the result of H5Dread and H5DOread_chunk. */ - for(i=0; ioloc.file) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - - if(mem_space_id < 0 || file_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") + if(mem_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid mem_space_id") + if(file_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file_space_id") if(H5S_ALL != mem_space_id) { if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) @@ -215,6 +216,76 @@ done: /*------------------------------------------------------------------------- + * Function: H5Dread_chunk + * + * Purpose: Reads an entire chunk from the file directly. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Matthew Strong (GE Healthcare) + * 14 February 2016 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, + void *buf) +{ + hbool_t created_dxpl = FALSE; /* Whether we created a DXPL */ + hbool_t do_direct_read = TRUE; /* Flag for direct writes */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "ii*h*Iu*x", dset_id, dxpl_id, offset, filters, buf); + + /* Check arguments */ + if(dset_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset ID") + if(!buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") + if(!offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") + if(!filters) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filters cannot be NULL") + + /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ + if(H5P_DEFAULT == dxpl_id) { + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "cannot create dxpl") + created_dxpl = TRUE; + } /* end if */ + + /* Set direct write parameters */ + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FLAG_NAME, &do_direct_read) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set direct read property") + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_OFFSET_NAME, &offset) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set offset property") + + /* Read chunk */ + if(H5Dread(dset_id, 0, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "cannot read from dataset") + + /* Get the filter mask */ + if(H5Pget(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FILTERS_NAME, filters) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "cannot get filter mask property") + +done: + if(created_dxpl) { + if(H5Pclose(dxpl_id) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close dxpl") + } /* end if */ + else { + /* Reset the direct read flag on user DXPL */ + do_direct_read = FALSE; + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_READ_FLAG_NAME, &do_direct_read) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot reset direct write property") + } + + FUNC_LEAVE_API(ret_value) +} /* end H5Dread_chunk() */ + + +/*------------------------------------------------------------------------- * Function: H5Dwrite * * Purpose: Writes (part of) a DSET from application memory BUF to the @@ -311,6 +382,80 @@ done: /*------------------------------------------------------------------------- + * Function: H5Dwrite_chunk + * + * Purpose: Writes an entire chunk to the file directly. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 30 July 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, + size_t data_size, const void *buf) +{ + hbool_t created_dxpl = FALSE; /* Whether we created a DXPL */ + hbool_t do_direct_write = TRUE; /* Flag for direct writes */ + uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iiIu*hz*x", dset_id, dxpl_id, filters, offset, data_size, buf); + + /* Check arguments */ + if(dset_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset ID") + if(!buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") + if(!offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") + if(!data_size) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data_size cannot be NULL") + data_size_32 = (uint32_t)data_size; + if(data_size != (size_t)data_size_32) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data_size") + + /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ + if(H5P_DEFAULT == dxpl_id) { + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "cannot create dxpl") + created_dxpl = TRUE; + } /* end if */ + + /* Set direct write parameters */ + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &do_direct_write) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set direct read property") + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME, &filters) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set filters property") + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME, &offset) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set offset property") + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME, &data_size_32) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot set data size property") + + /* Write chunk */ + if(H5Dwrite(dset_id, 0, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "cannot write to dataset") + +done: + if(created_dxpl) { + if(H5Pclose(dxpl_id) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close dxpl") + } /* end if */ + else { + /* Reset the direct write flag on user DXPL */ + do_direct_write = FALSE; + if(H5Pset(dxpl_id, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &do_direct_write) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "cannot reset direct write property") + } + + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite_chunk() */ + + +/*------------------------------------------------------------------------- * Function: H5D__pre_write * * Purpose: Preparation for writing data. diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 790674a..be80cef 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -157,6 +157,10 @@ H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf/*out*/); H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf); +H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, + const hsize_t *offset, size_t data_size, const void *buf); +H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, + const hsize_t *offset, uint32_t *filters, void *buf); H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op, void *operator_data); H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ec560f2..0d93211 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -214,6 +214,7 @@ set (H5_TESTS cmpd_dset filter_fail extend + direct_chunk external efc objcopy diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 04cc41f..6f914ba 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -532,6 +532,7 @@ set (test_CLEANFILES vds_swmr.h5 vds_swmr_src_*.h5 tmp/vds_src_2.h5 + direct_chunk.h5 ) # Remove any output file left over from previous test run diff --git a/test/Makefile.am b/test/Makefile.am index ab81f50..8f671ac 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -55,11 +55,12 @@ TEST_PROG= testhdf5 \ cache cache_api cache_image cache_tagging lheap ohdr stab gheap \ evict_on_close farray earray btree2 fheap \ pool accum hyperslab istore bittests dt_arith page_buffer \ - dtypes dsets cmpd_dset filter_fail extend external efc objcopy links unlink \ - twriteorder big mtime fillval mount flush1 flush2 app_ref enum \ - set_extent ttsafe enc_dec_plist enc_dec_plist_cross_platform\ - getname vfd ntypes dangle dtransform reserved cross_read \ - freespace mf vds file_image unregister cache_logging cork swmr + dtypes dsets cmpd_dset filter_fail extend direct_chunk external efc \ + objcopy links unlink twriteorder big mtime fillval mount \ + flush1 flush2 app_ref enum set_extent ttsafe enc_dec_plist \ + enc_dec_plist_cross_platform getname vfd ntypes dangle dtransform \ + reserved cross_read freespace mf vds file_image unregister \ + cache_logging cork swmr # List programs to be built when testing here. # error_test and err_compat are built at the same time as the other tests, but executed by testerror.sh. @@ -190,7 +191,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse flushrefresh_VERIFICATION_DONE atomic_data accum_swmr_big.h5 ohdr_swmr.h5 \ test_swmr*.h5 cache_logging.h5 cache_logging.out vds_swmr.h5 vds_swmr_src_*.h5 \ swmr[0-2].h5 swmr_writer.out swmr_writer.log.* swmr_reader.out.* swmr_reader.log.* \ - tbogus.h5.copy cache_image_test.h5 + tbogus.h5.copy cache_image_test.h5 direct_chunk.h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/direct_chunk.c b/test/direct_chunk.c new file mode 100644 index 0000000..2ef38ea --- /dev/null +++ b/test/direct_chunk.c @@ -0,0 +1,2167 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* Copyright by The HDF Group. * +* Copyright by the Board of Trustees of the University of Illinois. * +* All rights reserved. * +* * +* This file is part of HDF5. The full HDF5 copyright notice, including * +* terms governing use, modification, and redistribution, is contained in * + * 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. * +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "h5test.h" + +#if defined(H5_HAVE_ZLIB_H) && !defined(H5_ZLIB_HEADER) +# define H5_ZLIB_HEADER "zlib.h" +#endif +#if defined(H5_ZLIB_HEADER) +# include H5_ZLIB_HEADER /* "zlib.h" */ +#endif + +#define FILE_NAME "direct_chunk.h5" + +/* Datasets for Direct Write tests */ +#define DATASETNAME1 "direct_write" +#define DATASETNAME2 "skip_one_filter" +#define DATASETNAME3 "skip_two_filters" +#define DATASETNAME4 "data_conv" +#define DATASETNAME5 "contiguous_dset" +#define DATASETNAME6 "invalid_argue" +#define DATASETNAME7 "overwrite_chunk" +/* Datasets for Direct Read tests */ +#define DATASETNAME8 "disabled_chunk_cache" +#define DATASETNAME9 "flush_chunk_cache" +#define DATASETNAME10 "read_w_valid_cache" +#define DATASETNAME11 "unallocated_chunk" +#define DATASETNAME12 "unfiltered_data" + +#define RANK 2 +#define NX 16 +#define NY 16 +#define CHUNK_NX 4 +#define CHUNK_NY 4 + +#define DEFLATE_SIZE_ADJUST(s) (HDceil(((double)(s))*H5_DOUBLE(1.001))+H5_DOUBLE(12.0)) + +/* Temporary filter IDs used for testing */ +#define H5Z_FILTER_BOGUS1 305 +#define H5Z_FILTER_BOGUS2 306 +#define ADD_ON 7 +#define FACTOR 3 + +/* Constants for the overwrite test */ +#define OVERWRITE_NDIMS 3 +#define OVERWRITE_CHUNK_NX 3 +#define OVERWRITE_CHUNK_2NX 6 +#define OVERWRITE_CHUNK_NY 2 +#define OVERWRITE_VALUE 42 + +/* Defines used in test_single_chunk_latest() */ +#define FILE "single_latest.h5" +#define DATASET "dataset" +#define DIM0 4 +#define DIM1 32 +#define CHUNK0 DIM0 +#define CHUNK1 DIM1 + +/* Local prototypes for filter functions */ +static size_t filter_bogus1(unsigned int flags, size_t cd_nelmts, + const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf); +static size_t filter_bogus2(unsigned int flags, size_t cd_nelmts, + const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf); + +/* This message derives from H5Z */ +const H5Z_class2_t H5Z_BOGUS1[1] = {{ + H5Z_CLASS_T_VERS, /* H5Z_class_t version */ + H5Z_FILTER_BOGUS1, /* Filter id number */ + 1, 1, /* Encoding and decoding enabled */ + "bogus1", /* Filter name for debugging */ + NULL, /* The "can apply" callback */ + NULL, /* The "set local" callback */ + filter_bogus1, /* The actual filter function */ +}}; + +const H5Z_class2_t H5Z_BOGUS2[1] = {{ + H5Z_CLASS_T_VERS, /* H5Z_class_t version */ + H5Z_FILTER_BOGUS2, /* Filter id number */ + 1, 1, /* Encoding and decoding enabled */ + "bogus2", /* Filter name for debugging */ + NULL, /* The "can apply" callback */ + NULL, /* The "set local" callback */ + filter_bogus2, /* The actual filter function */ +}}; + +/*------------------------------------------------------------------------- + * Function: test_direct_chunk_write + * + * Purpose: Test the basic functionality of H5Dwrite_chunk + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Raymond Lu + * 30 November 2012 + * + *------------------------------------------------------------------------- + */ +#ifdef H5_HAVE_FILTER_DEFLATE +static int +test_direct_chunk_write (hid_t file) +{ + hid_t dataspace = -1, dataset = -1; + hid_t mem_space = -1; + hid_t cparms = -1, dxpl = -1; + hsize_t dims[2] = {NX, NY}; + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; + herr_t status; + int ret; + int data[NX][NY]; + int i, j, n; + + unsigned filter_mask = 0; + int direct_buf[CHUNK_NX][CHUNK_NY]; + int check_chunk[CHUNK_NX][CHUNK_NY]; + hsize_t offset[2] = {0, 0}; + size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + + const Bytef *z_src = (const Bytef*)(direct_buf); + Bytef *z_dst = NULL; /*destination buffer */ + uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + uLong z_src_nbytes = (uLong)buf_size; + int aggression = 9; /* Compression aggression setting */ + void *outbuf = NULL; /* Pointer to new buffer */ + + hsize_t start[2]; /* Start of hyperslab */ + hsize_t stride[2]; /* Stride of hyperslab */ + hsize_t count[2]; /* Block count */ + hsize_t block[2]; /* Block sizes */ + + TESTING("basic functionality of H5Dwrite_chunk"); + + /* + * Create the data space with unlimited dimensions. + */ + if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + + if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) + goto error; + + /* + * Modify dataset creation properties, i.e. enable chunking and compression + */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) + goto error; + + if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) + goto error; + + /* + * Create a new dataset within the file using cparms + * creation properties. + */ + if((dataset = H5Dcreate2(file, DATASETNAME1, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + goto error; + + /* Initialize the dataset */ + for(i = n = 0; i < NX; i++) + for(j = 0; j < NY; j++) + data[i][j] = n++; + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + /* + * Write the data for the dataset. It should stay in the chunk cache. + * It will be evicted from the cache by the H5Dwrite_chunk calls. + */ + if((status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl, data)) < 0) + goto error; + + /* Initialize data for one chunk */ + for(i = n = 0; i < CHUNK_NX; i++) + for(j = 0; j < CHUNK_NY; j++) + direct_buf[i][j] = n++; + + /* Allocate output (compressed) buffer */ + outbuf = HDmalloc(z_dst_nbytes); + z_dst = (Bytef *)outbuf; + + /* Perform compression from the source to the destination buffer */ + ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); + + /* Check for various zlib errors */ + if(Z_BUF_ERROR == ret) { + HDfprintf(stderr, "overflow"); + goto error; + } else if(Z_MEM_ERROR == ret) { + HDfprintf(stderr, "deflate memory error"); + goto error; + } else if(Z_OK != ret) { + HDfprintf(stderr, "other deflate error"); + goto error; + } + + /* Write the compressed chunk data repeatedly to cover all the chunks in the + * dataset, using the direct writing function. */ + for(i=0; i0) { + *int_ptr++ -= (int)ADD_ON; + buf_left -= (ssize_t)sizeof(int); + } /* end while */ + } /* end if */ + else { /* write */ + /* Add the "add on" value to all the data values */ + while(buf_left>0) { + *int_ptr++ += (int)ADD_ON; + buf_left -= (ssize_t)sizeof(int); + } /* end while */ + } /* end else */ + + return nbytes; +} /* filter_bogus1() */ + +/*------------------------------------------------------------------------- + * Function: filter_bogus2 + * + * Purpose: A bogus filter that multiplies the original value by FACTOR. + * + * Return: Success: Data chunk size + * + * Programmer: Raymond Lu + * 30 November 2012 + *------------------------------------------------------------------------- + */ +static size_t +filter_bogus2(unsigned int flags, size_t H5_ATTR_UNUSED cd_nelmts, + const unsigned int H5_ATTR_UNUSED *cd_values, size_t nbytes, + size_t *buf_size, void **buf) +{ + int *int_ptr=(int *)*buf; /* Pointer to the data values */ + ssize_t buf_left=(ssize_t)*buf_size; /* Amount of data buffer left to process */ + + if(flags & H5Z_FLAG_REVERSE) { /* read */ + /* Substract the "add on" value to all the data values */ + while(buf_left>0) { + *int_ptr++ /= (int)FACTOR; + buf_left -= (ssize_t)sizeof(int); + } /* end while */ + } /* end if */ + else { /* write */ + /* Add the "add on" value to all the data values */ + while(buf_left>0) { + *int_ptr++ *= (int)FACTOR; + buf_left -= (ssize_t)sizeof(int); + } /* end while */ + } /* end else */ + + return nbytes; +} /* filter_bogus2() */ + +/*------------------------------------------------------------------------- + * Function: test_skip_compress_write2 + * + * Purpose: Test skipping compression filter when there are three filters + * for the dataset + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Raymond Lu + * 30 November 2012 + * + *------------------------------------------------------------------------- + */ +static int +test_skip_compress_write2(hid_t file) +{ + hid_t dataspace = -1, dataset = -1; + hid_t mem_space = -1; + hid_t cparms = -1, dxpl = -1; + hsize_t dims[2] = {NX, NY}; + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; + herr_t status; + int i, j, n; + + unsigned filter_mask = 0; /* orig filter mask */ + int origin_direct_buf[CHUNK_NX][CHUNK_NY]; + int direct_buf[CHUNK_NX][CHUNK_NY]; + int check_chunk[CHUNK_NX][CHUNK_NY]; + hsize_t offset[2] = {0, 0}; + size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + int aggression = 9; /* Compression aggression setting */ + + unsigned read_filter_mask = 0; /* filter mask after direct read */ + int read_direct_buf[CHUNK_NX][CHUNK_NY]; + hsize_t read_buf_size = 0; /* buf size */ + + hsize_t start[2]; /* Start of hyperslab */ + hsize_t stride[2]; /* Stride of hyperslab */ + hsize_t count[2]; /* Block count */ + hsize_t block[2]; /* Block sizes */ + + TESTING("skipping compression filters but keep two other filters"); + + /* + * Create the data space with unlimited dimensions. + */ + if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + + if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) + goto error; + + /* + * Modify dataset creation properties, i.e. enable chunking and compression. + * The order of filters is bogus 1 + deflate + bogus 2. + */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) + goto error; + + /* Register and enable first bogus filter */ + if(H5Zregister (H5Z_BOGUS1) < 0) + goto error; + + if(H5Pset_filter(cparms, H5Z_FILTER_BOGUS1, 0, (size_t)0, NULL) < 0) + goto error; + + /* Enable compression filter */ + if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) + goto error; + + /* Register and enable second bogus filter */ + if(H5Zregister (H5Z_BOGUS2) < 0) + goto error; + + if(H5Pset_filter(cparms, H5Z_FILTER_BOGUS2, 0, (size_t)0, NULL) < 0) + goto error; + + /* + * Create a new dataset within the file using cparms + * creation properties. + */ + if((dataset = H5Dcreate2(file, DATASETNAME3, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + goto error; + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + /* Initialize data for one chunk. Apply operations of two bogus filters to the chunk */ + for(i = n = 0; i < CHUNK_NX; i++) + for(j = 0; j < CHUNK_NY; j++) { + origin_direct_buf[i][j] = n++; + direct_buf[i][j] = (origin_direct_buf[i][j] + ADD_ON) * FACTOR; + } + + /* write the uncompressed chunk data repeatedly to dataset, using the direct writing function. + * Indicate skipping the compression filter but keep the other two bogus filters */ + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY; + + /* compression filter is the middle one to be skipped */ + filter_mask = 0x00000002; + + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) < 0) + goto error; + + if(H5Fflush(dataset, H5F_SCOPE_LOCAL) < 0) + goto error; + + if(H5Dclose(dataset) < 0) + goto error; + + if((dataset = H5Dopen2(file, DATASETNAME3, H5P_DEFAULT)) < 0) + goto error; + + /* + * Select hyperslab for one chunk in the file + */ + start[0] = CHUNK_NX; start[1] = CHUNK_NY; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = CHUNK_NX; block[1] = CHUNK_NY; + if((status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, stride, count, block)) < 0) + goto error; + + /* Read the chunk back */ + if((status = H5Dread(dataset, H5T_NATIVE_INT, mem_space, dataspace, H5P_DEFAULT, check_chunk)) < 0) + goto error; + + /* Check that the values read are the same as the values written */ + for(i = 0; i < CHUNK_NX; i++) { + for(j = 0; j < CHUNK_NY; j++) { + if(origin_direct_buf[i][j] != check_chunk[i][j]) { + HDprintf(" 1. Read different values than written."); + HDprintf(" At index %d,%d\n", i, j); + HDprintf(" origin_direct_buf=%d, check_chunk=%d\n", origin_direct_buf[i][j], check_chunk[i][j]); + goto error; + } + } + } + + /* Query chunk storage size */ + if((status = H5Dget_chunk_storage_size(dataset, offset, &read_buf_size)) < 0) + goto error; + if(read_buf_size != buf_size) + goto error; + + /* Read the raw chunk back */ + HDmemset(&read_direct_buf, 0, sizeof(read_direct_buf)); + if((status = H5Dread_chunk(dataset, H5P_DEFAULT, offset, &read_filter_mask, read_direct_buf)) < 0) + goto error; + if(read_filter_mask != filter_mask) + goto error; + + /* Check that the direct chunk read is the same as the chunk written */ + for(i = 0; i < CHUNK_NX; i++) { + for(j = 0; j < CHUNK_NY; j++) { + if(direct_buf[i][j] != read_direct_buf[i][j]) { + HDprintf(" 1. Read different values than written."); + HDprintf(" At index %d,%d\n", i, j); + HDprintf(" direct_buf=%d, read_direct_buf=%d\n", direct_buf[i][j], read_direct_buf[i][j]); + goto error; + } + } + } + + /* + * Close/release resources. + */ + H5Dclose(dataset); + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(dataset); + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + } H5E_END_TRY; + + H5_FAILED(); + return 1; +} /* test_skip_compress_write2() */ + +/*------------------------------------------------------------------------- + * Function: test_data_conv + * + * Purpose: Test data conversion + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Raymond Lu + * 30 November 2012 + * + *------------------------------------------------------------------------- + */ +static int +test_data_conv(hid_t file) +{ + typedef struct { + int a, b, c[4], d, e; + } src_type_t; + typedef struct { + int a, c[4], e; + } dst_type_t; + + hid_t dataspace = -1, dataset = -1; + hid_t mem_space = -1; + hid_t cparms = -1, dxpl = -1; + hsize_t dims[2] = {NX, NY}; + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; + herr_t status; + int i, j, n; + const hsize_t four = 4; + hid_t st=-1, dt=-1; + hid_t array_dt; + + unsigned filter_mask = 0; + src_type_t direct_buf[CHUNK_NX][CHUNK_NY]; + dst_type_t check_chunk[CHUNK_NX][CHUNK_NY]; + src_type_t read_chunk[CHUNK_NX][CHUNK_NY]; /* For H5Dread_chunk */ + + hsize_t offset[2] = {0, 0}; + size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(src_type_t); + + hsize_t start[2]; /* Start of hyperslab */ + hsize_t stride[2]; /* Stride of hyperslab */ + hsize_t count[2]; /* Block count */ + hsize_t block[2]; /* Block sizes */ + + TESTING("data conversion for H5Dwrite_chunk/H5Dread_chunk"); + + /* + * Create the data space with unlimited dimensions. + */ + if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + + if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) + goto error; + + /* + * Modify dataset creation properties, i.e. enable chunking + */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) + goto error; + + /* Build hdf5 datatypes */ + array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, &four); + if((st = H5Tcreate(H5T_COMPOUND, sizeof(src_type_t))) < 0 || + H5Tinsert(st, "a", HOFFSET(src_type_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(st, "b", HOFFSET(src_type_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(st, "c", HOFFSET(src_type_t, c), array_dt) < 0 || + H5Tinsert(st, "d", HOFFSET(src_type_t, d), H5T_NATIVE_INT) < 0 || + H5Tinsert(st, "e", HOFFSET(src_type_t, e), H5T_NATIVE_INT) < 0) + goto error; + + if(H5Tclose(array_dt) < 0) + goto error; + + array_dt = H5Tarray_create2(H5T_NATIVE_INT, 1, &four); + if((dt = H5Tcreate(H5T_COMPOUND, sizeof(dst_type_t))) < 0 || + H5Tinsert(dt, "a", HOFFSET(dst_type_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(dt, "c", HOFFSET(dst_type_t, c), array_dt) < 0 || + H5Tinsert(dt, "e", HOFFSET(dst_type_t, e), H5T_NATIVE_INT) < 0) + goto error; + + if(H5Tclose(array_dt) < 0) + goto error; + + /* + * Create a new dataset within the file using cparms + * creation properties. + */ + if((dataset = H5Dcreate2(file, DATASETNAME4, st, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + goto error; + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + /* Initialize data for one chunk */ + for(i = n = 0; i < CHUNK_NX; i++) { + for(j = 0; j < CHUNK_NY; j++) { + (direct_buf[i][j]).a = i*j+0; + (direct_buf[i][j]).b = i*j+1; + (direct_buf[i][j]).c[0] = i*j+2; + (direct_buf[i][j]).c[1] = i*j+3; + (direct_buf[i][j]).c[2] = i*j+4; + (direct_buf[i][j]).c[3] = i*j+5; + (direct_buf[i][j]).d = i*j+6; + (direct_buf[i][j]).e = i*j+7; + } + } + + /* write the chunk data to dataset, using the direct writing function. + * There should be no data conversion involved. */ + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY; + + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) < 0) + goto error; + + if(H5Fflush(dataset, H5F_SCOPE_LOCAL) < 0) + goto error; + + if(H5Dclose(dataset) < 0) + goto error; + + if((dataset = H5Dopen2(file, DATASETNAME4, H5P_DEFAULT)) < 0) + goto error; + + /* Use H5Dread_chunk() to read the uncompressed data */ + if((status = H5Dread_chunk(dataset, dxpl, offset, &filter_mask, read_chunk)) < 0) + goto error; + + /* Check that the values read are the same as the values written */ + for(i = 0; i < CHUNK_NX; i++) { + for(j = 0; j < CHUNK_NY; j++) { + if ((direct_buf[i][j]).a != (read_chunk[i][j]).a || + (direct_buf[i][j]).b != (read_chunk[i][j]).b || + (direct_buf[i][j]).c[0] != (read_chunk[i][j]).c[0] || + (direct_buf[i][j]).c[1] != (read_chunk[i][j]).c[1] || + (direct_buf[i][j]).c[2] != (read_chunk[i][j]).c[2] || + (direct_buf[i][j]).c[3] != (read_chunk[i][j]).c[3] || + (direct_buf[i][j]).d != (read_chunk[i][j]).d || + (direct_buf[i][j]).e != (read_chunk[i][j]).e) { + HDprintf(" 1. Read different values than written."); + HDprintf(" At index %d,%d\n", i, j); + HDprintf(" src={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", + (direct_buf[i][j]).a, (direct_buf[i][j]).b, (direct_buf[i][j]).c[0], (direct_buf[i][j]).c[1], + (direct_buf[i][j]).c[2], (direct_buf[i][j]).c[3], (direct_buf[i][j]).d, (direct_buf[i][j]).e); + HDprintf(" dst={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", + (read_chunk[i][j]).a, (read_chunk[i][j]).b, (read_chunk[i][j]).c[0], (read_chunk[i][j]).c[1], + (read_chunk[i][j]).c[2], (read_chunk[i][j]).c[3], (read_chunk[i][j]).d, (read_chunk[i][j]).e); + + goto error; + } + } + } + + /* + * Select hyperslab for the chunk just written in the file + */ + start[0] = CHUNK_NX; start[1] = CHUNK_NY; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = CHUNK_NX; block[1] = CHUNK_NY; + if((status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, stride, count, block)) < 0) + goto error; + + /* Read the chunk back. Data should be converted */ + if((status = H5Dread(dataset, dt, mem_space, dataspace, H5P_DEFAULT, check_chunk)) < 0) + goto error; + + /* Check that the values read are the same as the values written */ + for(i = 0; i < CHUNK_NX; i++) { + for(j = 0; j < CHUNK_NY; j++) { + if ((direct_buf[i][j]).a != (check_chunk[i][j]).a || + (direct_buf[i][j]).c[0] != (check_chunk[i][j]).c[0] || + (direct_buf[i][j]).c[1] != (check_chunk[i][j]).c[1] || + (direct_buf[i][j]).c[2] != (check_chunk[i][j]).c[2] || + (direct_buf[i][j]).c[3] != (check_chunk[i][j]).c[3] || + (direct_buf[i][j]).e != (check_chunk[i][j]).e) { + HDprintf(" 1. Read different values than written."); + HDprintf(" At index %d,%d\n", i, j); + HDprintf(" src={a=%d, b=%d, c=[%d,%d,%d,%d], d=%d, e=%d\n", + (direct_buf[i][j]).a, (direct_buf[i][j]).b, (direct_buf[i][j]).c[0], (direct_buf[i][j]).c[1], + (direct_buf[i][j]).c[2], (direct_buf[i][j]).c[3], (direct_buf[i][j]).d, (direct_buf[i][j]).e); + HDprintf(" dst={a=%d, c=[%d,%d,%d,%d], e=%d\n", + (check_chunk[i][j]).a, (check_chunk[i][j]).c[0], (check_chunk[i][j]).c[1], (check_chunk[i][j]).c[2], + (check_chunk[i][j]).c[3], (check_chunk[i][j]).e); + + goto error; + } + } + } + + /* + * Close/release resources. + */ + H5Dclose(dataset); + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + H5Tclose(st); + H5Tclose(dt); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(dataset); + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + H5Tclose(st); + H5Tclose(dt); + } H5E_END_TRY; + + H5_FAILED(); + return 1; +} /* test_data_conv() */ + +/*------------------------------------------------------------------------- + * Function: test_invalid_parameters + * + * Purpose: Test invalid parameters for H5Dwrite_chunk and H5Dread_chunk + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Raymond Lu + * 30 November 2012 + * + *------------------------------------------------------------------------- + */ +static int +test_invalid_parameters(hid_t file) +{ + hid_t dataspace = -1, dataset = -1; + hid_t mem_space = -1; + hid_t cparms = -1, dxpl = -1; + hsize_t dims[2] = {NX, NY}; + hsize_t chunk_dims[2] ={CHUNK_NX, CHUNK_NY}; + herr_t status; + int i, j, n; + + unsigned filter_mask = 0; + int direct_buf[CHUNK_NX][CHUNK_NY]; + hsize_t offset[2] = {0, 0}; + size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + int aggression = 9; /* Compression aggression setting */ + + hsize_t chunk_nbytes; /* Chunk size */ + + TESTING("invalid parameters for H5Dwrite_chunk/H5Dread_chunk"); + + /* + * Create the data space with unlimited dimensions. + */ + if((dataspace = H5Screate_simple(RANK, dims, NULL)) < 0) + goto error; + + if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) + goto error; + + /* + * Modify dataset creation properties + */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + + /* + * Create a new contiguous dataset to verify H5Dwrite_chunk/H5Dread_chunk doesn't work + */ + if((dataset = H5Dcreate2(file, DATASETNAME5, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + goto error; + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + /* Initialize data for one chunk */ + for(i = n = 0; i < CHUNK_NX; i++) + for(j = 0; j < CHUNK_NY; j++) { + direct_buf[i][j] = n++; + } + + /* Try to write the chunk data to contiguous dataset. It should fail */ + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY; + + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Try to get chunk size for a contiguous dataset. It should fail */ + H5E_BEGIN_TRY { + if((status = H5Dget_chunk_storage_size(dataset, offset, &chunk_nbytes)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Try to H5Dread_chunk from the contiguous dataset. It should fail */ + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + if(H5Dclose(dataset) < 0) + goto error; + + + /* Create a chunked dataset with compression filter */ + if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) + goto error; + + if((status = H5Pset_deflate( cparms, (unsigned ) aggression)) < 0) + goto error; + + /* + * Create a new dataset within the file using cparms + * creation properties. + */ + if((dataset = H5Dcreate2(file, DATASETNAME6, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + goto error; + + /* Check invalid dataset ID for H5Dwrite_chunk and H5Dread_chunk */ + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk((hid_t)-1, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk((hid_t)-1, dxpl, offset, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check invalid DXPL ID for H5Dwrite_chunk and H5Dread_chunk */ + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, (hid_t)-1, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, (hid_t)-1, offset, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check invalid OFFSET for H5Dwrite_chunk and H5Dread_chunk */ + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, NULL, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, dxpl, NULL, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check when OFFSET is out of dataset range for H5Dwrite_chunk and H5Dread_chunk */ + offset[0] = NX + 1; + offset[1] = NY; + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check when OFFSET is not on chunk boundary for H5Dwrite_chunk and H5Dread_chunk */ + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY + 1; + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, dxpl, offset, &filter_mask, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check invalid buffer size for H5Dwrite_chunk only */ + offset[0] = CHUNK_NX; + offset[1] = CHUNK_NY; + buf_size = 0; + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, direct_buf)) != FAIL) + goto error; + } H5E_END_TRY; + + /* Check invalid data buffer for H5Dwrite_chunk and H5Dread_chunk */ + buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + H5E_BEGIN_TRY { + if((status = H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, buf_size, NULL)) != FAIL) + goto error; + } H5E_END_TRY; + + H5E_BEGIN_TRY { + if((status = H5Dread_chunk(dataset, dxpl, offset, &filter_mask, NULL)) != FAIL) + goto error; + } H5E_END_TRY; + + if(H5Dclose(dataset) < 0) + goto error; + + /* + * Close/release resources. + */ + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(dataset); + H5Sclose(mem_space); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Pclose(dxpl); + } H5E_END_TRY; + + H5_FAILED(); + return 1; +} /* test_invalid_parameters() */ + +/*------------------------------------------------------------------------- + * Function: test_direct_chunk_read_no_cache + * + * Purpose: Test the basic functionality of H5Dread_chunk with the + * chunk cache diabled. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Matthew Strong (GE Healthcare) + * 14 February 2016 + * + *------------------------------------------------------------------------- + */ +#ifdef H5_HAVE_FILTER_DEFLATE +static int +test_direct_chunk_read_no_cache (hid_t file) +{ + hid_t dataspace = -1, dataset = -1; + hid_t mem_space = -1; + hid_t cparms = -1, dxpl = -1, dapl = -1; + hsize_t dims[2] = {NX, NY}; + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t chunk_dims[2] = {CHUNK_NX, CHUNK_NY}; + herr_t status; /* status from H5 function calls */ + int ret; /* deflate return status */ + int data[NX][NY]; + int i, j, k, l, n; /* local index variables */ + + unsigned filter_mask = 0; /* filter mask returned from H5Dread_chunk */ + int direct_buf[CHUNK_NX][CHUNK_NY]; /* chunk read with H5Dread and manually decompressed */ + int check_chunk[CHUNK_NX][CHUNK_NY]; /* chunk read with H5Dread */ + hsize_t offset[2]; /* chunk offset used for H5Dread_chunk */ + size_t buf_size = CHUNK_NX*CHUNK_NY*sizeof(int); + + Bytef *z_src = NULL; /* source buffer */ + uLongf z_src_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + Bytef *z_dst = (Bytef*)(direct_buf); + uLong z_dst_nbytes = (uLong)buf_size; + int aggression = 9; /* Compression aggression setting */ + void *outbuf = NULL; /* Pointer to new buffer */ + + hsize_t start[2]; /* Start of hyperslab */ + hsize_t stride[2]; /* Stride of hyperslab */ + hsize_t count[2]; /* Block count */ + hsize_t block[2]; /* Block sizes */ + + TESTING("basic functionality of H5Dread_chunk (chunk cache disabled)"); + + /* Create the data space with unlimited dimensions. */ + if((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0) + goto error; + if((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0) + goto error; + + /* Modify dataset creation properties, i.e. enable chunking and compression */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + if((status = H5Pset_chunk( cparms, RANK, chunk_dims)) < 0) + goto error; + if((status = H5Pset_deflate( cparms, (unsigned) aggression)) < 0) + goto error; + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + goto error; + + /* Disable chunk cache by setting number of slots to 0 */ + if((status = H5Pset_chunk_cache(dapl, 0, H5D_CHUNK_CACHE_NBYTES_DEFAULT, H5D_CHUNK_CACHE_W0_DEFAULT)) < 0) + goto error; + + /* Create a new dataset within the file using cparms creation properties. */ + if((dataset = H5Dcreate2(file, DATASETNAME8, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, dapl)) < 0) + goto error; + + /* Initialize the dataset */ + for(i = n = 0; i < NX; i++) + for(j = 0; j < NY; j++) + data[i][j] = n++; + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + goto error; + + /* Write the data for the dataset. + * Data will skip chunk cache and go directly to disk. */ + if((status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl, data)) < 0) + goto error; + + /* Allocate output (compressed) buffer */ + outbuf = HDmalloc(z_src_nbytes); + z_src = (Bytef *)outbuf; + + /* For each chunk in the dataset, compare the result of H5Dread and H5Dread_chunk. */ + for(i=0; i + +#if !defined(WIN32) && !defined(__MINGW32__) + +#include + +#ifdef H5_STDC_HEADERS +# include +# include +# include +# include +#endif + +#ifdef H5_HAVE_UNISTD_H +# include +# include +#endif + +#ifdef H5_HAVE_SYS_STAT_H +# include +#endif + +#if defined(H5_TIME_WITH_SYS_TIME) +# include +# include +#elif defined(H5_HAVE_SYS_TIME_H) +# include +#else +# include +#endif + +const char *FILENAME[] = { + "direct_write", + "unix.raw", + NULL +}; + +/* + * Print the current location on the standard output stream. + */ +#define FUNC __func__ +#define AT() printf (" at %s:%d in %s()...\n", \ + __FILE__, __LINE__, FUNC); +#define H5_FAILED() {puts("*FAILED*");fflush(stdout);} +#define TEST_ERROR {H5_FAILED(); AT(); goto error;} +#define TESTING(WHAT) {printf("Testing %-62s",WHAT); fflush(stdout);} +#define PASSED() {puts(" PASSED");fflush(stdout);} + +#define DIRECT_UNCOMPRESSED_DSET "direct_uncompressed_dset" +#define DIRECT_COMPRESSED_DSET "direct_compressed_dset" +#define REG_COMPRESSED_DSET "reg_compressed_dset" +#define REG_NO_COMPRESS_DSET "reg_no_compress_dset" +#define RANK 3 +#define NX 100 +#define NY 1000 +#define NZ 250 +#define CHUNK_NX 1 +#define CHUNK_NY 1000 +#define CHUNK_NZ 250 + +#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s))*1.001)+12) +char filename[1024]; +unsigned int *outbuf[NX]; +size_t data_size[NX]; +double total_size = 0.0; +unsigned int *direct_buf[NX]; +double MB = 1048576.0; + +/*-------------------------------------------------- + * Function to report IO rate + *-------------------------------------------------- + */ +void reportTime(struct timeval start, double mbytes) +{ + struct timeval timeval_stop,timeval_diff; + + /*end timing*/ + gettimeofday(&timeval_stop,NULL); + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec=timeval_stop.tv_usec-start.tv_usec; + timeval_diff.tv_sec=timeval_stop.tv_sec-start.tv_sec; + + if(timeval_diff.tv_usec<0) { + timeval_diff.tv_usec+=1000000; + timeval_diff.tv_sec--; + } /* end if */ + +/*printf("mbytes=%lf, sec=%lf, usec=%lf\n", mbytes, (double)timeval_diff.tv_sec, (double)timeval_diff.tv_usec);*/ + printf("MBytes/second: %lf\n", (double)mbytes/((double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0))); +} + +/*-------------------------------------------------- + * Create file, datasets, and initialize data + *-------------------------------------------------- + */ +int create_file(hid_t fapl_id) +{ + hid_t file; /* handles */ + hid_t fapl; + hid_t cparms; + hid_t dataspace, dataset; + hsize_t dims[RANK] = {NX, NY, NZ}; + hsize_t chunk_dims[RANK] ={CHUNK_NX, CHUNK_NY, CHUNK_NZ}; + unsigned int aggression = 9; /* Compression aggression setting */ + int ret; + int i, j, n; + + int flag; + int unix_file; + + unsigned int *p; + size_t buf_size = CHUNK_NY*CHUNK_NZ*sizeof(unsigned int); + + const Bytef *z_src; + Bytef *z_dst; /*destination buffer */ + uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + uLong z_src_nbytes = (uLong)buf_size; + + TESTING("Create a file and dataset"); + + /* + * Create the data space with unlimited dimensions. + */ + if((dataspace = H5Screate_simple(RANK, dims, NULL)) < 0) + TEST_ERROR; + + /* + * Create a new file. If file exists its contents will be overwritten. + */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) + TEST_ERROR; + + /* + * Modify dataset creation properties, i.e. enable chunking and compression + */ + if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR; + + if(H5Pset_chunk( cparms, RANK, chunk_dims) < 0) + TEST_ERROR; + + /* + * Create a new dataset within the file using cparms + * creation properties. + */ + if((dataset = H5Dcreate2(file, DIRECT_UNCOMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dataset) < 0) + TEST_ERROR; + + if((dataset = H5Dcreate2(file, REG_NO_COMPRESS_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dataset) < 0) + TEST_ERROR; + + /* Set compression */ + if(H5Pset_deflate( cparms, aggression) < 0) + TEST_ERROR; + + if((dataset = H5Dcreate2(file, DIRECT_COMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dataset) < 0) + TEST_ERROR; + + + if((dataset = H5Dcreate2(file, REG_COMPRESSED_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, + cparms, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dataset) < 0) + TEST_ERROR; + + if(H5Fclose(file) < 0) + TEST_ERROR; + + if(H5Sclose(dataspace) < 0) + TEST_ERROR; + + if(H5Pclose(cparms) < 0) + TEST_ERROR; + + /* create a unix file*/ + flag = O_CREAT|O_TRUNC|O_WRONLY; + + if ((unix_file=open(FILENAME[1],flag,S_IRWXU))== -1) + TEST_ERROR; + + if (close(unix_file) < 0) + { + printf(" unable to close the file\n"); + TEST_ERROR; + } + + + /* Initialize data for chunks */ + for(i = 0; i < NX; i++) { + p = direct_buf[i] = (unsigned int*)malloc(CHUNK_NY*CHUNK_NZ*sizeof(unsigned int)); + + for(j=0; j < CHUNK_NY*CHUNK_NZ; j++, p++) + *p = rand() % 65000; + + z_src = (const Bytef*)direct_buf[i]; + + z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(buf_size); + /* Allocate output (compressed) buffer */ + outbuf[i] = (unsigned int*)malloc((size_t)z_dst_nbytes); + z_dst = (Bytef *)outbuf[i]; + + /* Perform compression from the source to the destination buffer */ + ret = compress2(z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); + + data_size[i] = (size_t)z_dst_nbytes; + total_size += data_size[i]; + + /* Check for various zlib errors */ + if(Z_BUF_ERROR == ret) { + fprintf(stderr, "overflow"); + TEST_ERROR; + } else if(Z_MEM_ERROR == ret) { + fprintf(stderr, "deflate memory error"); + TEST_ERROR; + } else if(Z_OK != ret) { + fprintf(stderr, "other deflate error"); + TEST_ERROR; + } + } + + + PASSED(); + +error: + H5E_BEGIN_TRY { + H5Dclose(dataset); + H5Sclose(dataspace); + H5Pclose(cparms); + H5Fclose(file); + } H5E_END_TRY; + return 1; +} + +/*-------------------------------------------------- + * Benchmark the performance of the new function + * with precompressed data. + *-------------------------------------------------- + */ +int +test_direct_write_uncompressed_data(hid_t fapl_id) +{ + hid_t file; /* handles */ + hid_t dataspace, dataset; + hid_t dxpl; + herr_t status; + int i; + + unsigned filter_mask = 0; + hsize_t offset[RANK] = {0, 0, 0}; + + struct timeval timeval_start; + + TESTING("H5Dwrite_chunk for uncompressed data"); + + if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + TEST_ERROR; + + /* Start the timer */ + gettimeofday(&timeval_start,NULL); + + /* Reopen the file and dataset */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) + TEST_ERROR; + + if((dataset = H5Dopen2(file, DIRECT_UNCOMPRESSED_DSET, H5P_DEFAULT)) < 0) + TEST_ERROR; + + + /* Write the compressed chunk data repeatedly to cover all the chunks in the + * dataset, using the direct writing function. */ + for(i=0; i