/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 files COPYING and Copyright.html. COPYING can be found at the root * * of the source code distribution tree; Copyright.html can be found at the * * root level of an installed copy of the electronic HDF5 document set and * * is linked from the top-level documents page. It can also be found at * * http://hdfgroup.org/HDF5/doc/Copyright.html. 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 H5PSIdirect_write function * */ #include "h5test.h" #include #include #include #include #include #include #include const char *FILENAME[] = { "dectris_perf", "unix.raw", NULL }; #define DIRECT_DSET "direct_dset" #define COMPRESSED_DSET "compressed_dset" #define NO_COMPRESS_DSET "no_compress_dset" #define RANK 3 #define NX 100 #define NY 100 #define NZ 25 #define CHUNK_NX 1 #define CHUNK_NY 100 #define CHUNK_NZ 25 #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; 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, 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_DSET, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT)) < 0) TEST_ERROR; if(H5Dclose(dataset) < 0) TEST_ERROR; if((dataset = H5Dcreate2(file, 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; /* 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 *-------------------------------------------------- */ int test_direct_write(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+1] = {0, 0, 0, 0}; struct timeval timeval_start; TESTING("H5PSIdirect_write for DECTRIS project"); 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|H5F_ACC_SYNC, fapl_id)) < 0) TEST_ERROR; if((dataset = H5Dopen(file, DIRECT_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