//-------------------------------------------------------------------------- // Function: DSetCreatPropList::allFiltersAvail ///\brief Queries whether all the filters set in this property list /// are available currently. ///\return true if all filters available, and false if one or more /// filters not currently available ///\exception H5::PropListIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- bool DSetCreatPropList::allFiltersAvail() { htri_t ret_value = H5Pall_filters_avail(id); if( ret_value > 0 ) return true; else if( ret_value == 0 ) return false; else // Raise exception when H5Pall_filters_avail returns a negative value { throw PropListIException("DSetCreatPropList::allFiltersAvail", "H5Pall_filters_avail returned negative value"); } }
/*------------------------------------------------------------------------- * Function: ensure_filter_works * * Purpose: Tests writing entire data and partial data with filters * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t ensure_filter_works(hid_t fid, const char *name, hid_t dcpl_id) { hid_t did = -1; /* Dataset ID */ hid_t dxpl_id = -1; /* Dataset xfer property list ID */ hid_t write_dxpl_id = -1; /* Dataset xfer property list ID for writing */ hid_t sid = -1; /* Dataspace ID */ void *tconv_buf = NULL; /* Temporary conversion buffer */ int **orig = NULL; /* Data written to the dataset */ int **read = NULL; /* Data read from the dataset */ size_t r, c; /* Data rows and columns */ size_t hs_r, hs_c, hs_offr, hs_offc; /* Hypserslab sizes and offsets */ size_t i, j; /* Local index variables */ int n = 0; /* Value written to point array */ hbool_t are_same; /* Output from dataset compare function */ int ***save_array = NULL; /* (Global) array where the final data go */ /* initialize */ r = (size_t)sizes_g[0]; c = (size_t)sizes_g[1]; /* Create the data space */ if ((sid = H5Screate_simple(2, sizes_g, NULL)) < 0) TEST_ERROR; /* Allocate memory for the data buffers * We're using the hacky way of doing 2D arrays that uses a * single data buffer but which allows normal 2D access. */ if (allocate_and_init_2D_array(&orig, sizes_g, NULL) < 0) TEST_ERROR; if (allocate_and_init_2D_array(&read, sizes_g, NULL) < 0) TEST_ERROR; /* Create a small conversion buffer to test strip mining. We * might as well test all we can! */ if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR; if (NULL == (tconv_buf = HDcalloc((size_t)1000, sizeof(char)))) TEST_ERROR; if (H5Pset_buffer(dxpl_id, (size_t)1000, tconv_buf, NULL) < 0) TEST_ERROR; if ((write_dxpl_id = H5Pcopy(dxpl_id)) < 0) TEST_ERROR; TESTING(" filters (setup)"); /* Check if all the filters are available */ if (H5Pall_filters_avail(dcpl_id) != TRUE) TEST_ERROR; /* Create the dataset */ if ((did = H5Dcreate2(fid, name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 1: Read uninitialized data. It should be zero. *---------------------------------------------------------------------- */ TESTING(" filters (uninitialized read)"); if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, *read) < 0) TEST_ERROR; /* The input buffer was calloc'd and has not been initialized yet */ if (compare_2D_arrays(orig, read, sizes_g, &are_same) < 0) TEST_ERROR; if (FALSE == are_same) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 2: Test filters by setting up a chunked dataset and writing * to it. *---------------------------------------------------------------------- */ TESTING(" filters (write)"); n = 0; for (i = 0; i < r; i++) for (j = 0; j < c; j++) orig[i][j] = n++; if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl_id, *orig) < 0) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 3: Try to read the data we just wrote. *---------------------------------------------------------------------- */ TESTING(" filters (read)"); /* Read the dataset back */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, *read) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ if (compare_2D_arrays(orig, read, sizes_g, &are_same) < 0) TEST_ERROR; if (FALSE == are_same) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 4: Write new data over the top of the old data. The new data is * random thus not very compressible, and will cause the chunks to move * around as they grow. We only change values for the left half of the * dataset although we rewrite the whole thing. *---------------------------------------------------------------------- */ TESTING(" filters (modify)"); for (i = 0; i < r; i++) for (j = 0; j < c / 2; j++) orig[i][j] = (int)HDrandom() % RANDOM_LIMIT; if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl_id, *orig) < 0) TEST_ERROR; /* Read the dataset back and check it */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, *read) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ if (compare_2D_arrays(orig, read, sizes_g, &are_same) < 0) TEST_ERROR; if (FALSE == are_same) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 5: Close the dataset and then open it and read it again. This * insures that the filters message is picked up properly from the * object header. *---------------------------------------------------------------------- */ TESTING(" filters (re-open)"); if (H5Dclose(did) < 0) TEST_ERROR; if ((did = H5Dopen2(fid, name, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, *read) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ if (compare_2D_arrays(orig, read, sizes_g, &are_same) < 0) TEST_ERROR; if (FALSE == are_same) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 6: Test partial I/O by writing to and then reading from a * hyperslab of the dataset. The hyperslab does not line up on chunk * boundaries (we know that case already works from above tests). *---------------------------------------------------------------------- */ TESTING(" filters (partial I/O)"); hs_r = (size_t)hs_sizes_g[0]; hs_c = (size_t)hs_sizes_g[1]; hs_offr = (size_t)hs_offsets_g[0]; hs_offc = (size_t)hs_offsets_g[1]; for (i = 0; i < hs_r; i++) for (j = 0; j < hs_c; j++) orig[hs_offr + i][hs_offc + j] = (int)HDrandom() % RANDOM_LIMIT; if (H5Sselect_hyperslab(sid, H5S_SELECT_SET, hs_offsets_g, NULL, hs_sizes_g, NULL) < 0) TEST_ERROR; /* Use the "read" DXPL because partial I/O on corrupted data test * needs to ignore errors during writing */ if (H5Dwrite(did, H5T_NATIVE_INT, sid, sid, dxpl_id, *orig) < 0) TEST_ERROR; if (H5Dread(did, H5T_NATIVE_INT, sid, sid, dxpl_id, *read) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ if (compare_2D_arrays(orig, read, sizes_g, &are_same) < 0) TEST_ERROR; if (FALSE == are_same) TEST_ERROR; PASSED(); /* Save the data written to the file for later comparison when the file * is reopened for read test. */ if (!HDstrcmp(name, DSET_DEFLATE_NAME)) save_array = &orig_deflate_g; else if (!HDstrcmp(name, DSET_FILTER1_NAME)) save_array = &orig_dynlib1_g; else if (!HDstrcmp(name, DSET_FILTER2_NAME)) save_array = &orig_dynlib2_g; else if (!HDstrcmp(name, DSET_FILTER3_NAME)) save_array = &orig_dynlib4_g; else TEST_ERROR; if (allocate_and_init_2D_array(save_array, sizes_g, orig) < 0) TEST_ERROR; /* Clean up and exit */ if (H5Dclose(did) < 0) TEST_ERROR; if (H5Sclose(sid) < 0) TEST_ERROR; if (H5Pclose(dxpl_id) < 0) TEST_ERROR; if (H5Pclose(write_dxpl_id) < 0) TEST_ERROR; free_2D_array(&orig); free_2D_array(&read); HDfree(tconv_buf); return SUCCEED; error: /* Clean up objects used for this test */ H5E_BEGIN_TRY { H5Dclose(did); H5Sclose(sid); H5Pclose(dxpl_id); H5Pclose(write_dxpl_id); } H5E_END_TRY /* NULLs are okay here */ free_2D_array(&orig); free_2D_array(&read); if (tconv_buf) HDfree(tconv_buf); return FAIL; } /* end ensure_filter_works() */
/*------------------------------------------------------------------------- * Function: test_filter_internal * * Purpose: Tests writing entire data and partial data with filters * * Return: Success: 0 * Failure: -1 * * Programmer: Raymond Lu * 27 February 2013 * *------------------------------------------------------------------------- */ static herr_t test_filter_internal(hid_t fid, const char *name, hid_t dcpl) { hid_t dataset; /* Dataset ID */ hid_t dxpl; /* Dataset xfer property list ID */ hid_t write_dxpl; /* Dataset xfer property list ID for writing */ hid_t sid; /* Dataspace ID */ const hsize_t size[2] = {DSET_DIM1, DSET_DIM2}; /* Dataspace dimensions */ const hsize_t hs_offset[2] = {FILTER_HS_OFFSET1, FILTER_HS_OFFSET2}; /* Hyperslab offset */ const hsize_t hs_size[2] = {FILTER_HS_SIZE1, FILTER_HS_SIZE2}; /* Hyperslab size */ void *tconv_buf = NULL; /* Temporary conversion buffer */ int points[DSET_DIM1][DSET_DIM2], check[DSET_DIM1][DSET_DIM2]; size_t i, j; /* Local index variables */ int n = 0; /* Create the data space */ if((sid = H5Screate_simple(2, size, NULL)) < 0) goto error; /* * Create a small conversion buffer to test strip mining. We * might as well test all we can! */ if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) goto error; tconv_buf = HDmalloc((size_t)1000); if(H5Pset_buffer(dxpl, (size_t)1000, tconv_buf, NULL) < 0) goto error; if((write_dxpl = H5Pcopy(dxpl)) < 0) TEST_ERROR; TESTING(" filters (setup)"); /* Check if all the filters are available */ if(H5Pall_filters_avail(dcpl)!=TRUE) { H5_FAILED(); printf(" Line %d: Incorrect filter availability\n",__LINE__); goto error; } /* end if */ /* Create the dataset */ if((dataset = H5Dcreate2(fid, name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error; PASSED(); /*---------------------------------------------------------------------- * STEP 1: Read uninitialized data. It should be zero. *---------------------------------------------------------------------- */ TESTING(" filters (uninitialized read)"); if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) TEST_ERROR; for(i=0; i<(size_t)size[0]; i++) { for(j=0; j<(size_t)size[1]; j++) { if(0!=check[i][j]) { H5_FAILED(); printf(" Read a non-zero value.\n"); printf(" At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); goto error; } } } PASSED(); /*---------------------------------------------------------------------- * STEP 2: Test filters by setting up a chunked dataset and writing * to it. *---------------------------------------------------------------------- */ TESTING(" filters (write)"); n = 0; for(i=0; i<size[0]; i++) { for(j=0; j<size[1]; j++) { points[i][j] = (int)(n++); } } if(H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, points) < 0) TEST_ERROR; PASSED(); /*---------------------------------------------------------------------- * STEP 3: Try to read the data we just wrote. *---------------------------------------------------------------------- */ TESTING(" filters (read)"); /* Read the dataset back */ if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ for(i=0; i<size[0]; i++) { for(j=0; j<size[1]; j++) { if(points[i][j] != check[i][j]) { H5_FAILED(); fprintf(stderr," Read different values than written.\n"); fprintf(stderr," At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); fprintf(stderr," At original: %d\n", (int)points[i][j]); fprintf(stderr," At returned: %d\n", (int)check[i][j]); goto error; } } } PASSED(); /*---------------------------------------------------------------------- * STEP 4: Write new data over the top of the old data. The new data is * random thus not very compressible, and will cause the chunks to move * around as they grow. We only change values for the left half of the * dataset although we rewrite the whole thing. *---------------------------------------------------------------------- */ TESTING(" filters (modify)"); for(i=0; i<size[0]; i++) { for(j=0; j<size[1]/2; j++) { points[i][j] = (int)HDrandom () % RANDOM_LIMIT; } } if(H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, points) < 0) TEST_ERROR; /* Read the dataset back and check it */ if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ for(i=0; i<size[0]; i++) { for(j=0; j<size[1]; j++) { if(points[i][j] != check[i][j]) { H5_FAILED(); printf(" Read different values than written.\n"); printf(" At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); goto error; } } } PASSED(); /*---------------------------------------------------------------------- * STEP 5: Close the dataset and then open it and read it again. This * insures that the filters message is picked up properly from the * object header. *---------------------------------------------------------------------- */ TESTING(" filters (re-open)"); if(H5Dclose(dataset) < 0) TEST_ERROR; if((dataset = H5Dopen2(fid, name, H5P_DEFAULT)) < 0) TEST_ERROR; if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ for(i = 0; i < size[0]; i++) for(j = 0; j < size[1]; j++) if(points[i][j] != check[i][j]) { H5_FAILED(); printf(" Read different values than written.\n"); printf(" At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); goto error; } /* end if */ PASSED(); /*---------------------------------------------------------------------- * STEP 6: Test partial I/O by writing to and then reading from a * hyperslab of the dataset. The hyperslab does not line up on chunk * boundaries (we know that case already works from above tests). *---------------------------------------------------------------------- */ TESTING(" filters (partial I/O)"); for(i=0; i<(size_t)hs_size[0]; i++) { for(j=0; j<(size_t)hs_size[1]; j++) { points[(size_t)hs_offset[0]+i][(size_t)hs_offset[1]+j] = (int)HDrandom() % RANDOM_LIMIT; } } if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0) TEST_ERROR; /* (Use the "read" DXPL because partial I/O on corrupted data test needs to ignore errors during writing) */ if(H5Dwrite (dataset, H5T_NATIVE_INT, sid, sid, dxpl, points) < 0) TEST_ERROR; if(H5Dread (dataset, H5T_NATIVE_INT, sid, sid, dxpl, check) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ for(i=0; i<(size_t)hs_size[0]; i++) { for(j=0; j<(size_t)hs_size[1]; j++) { if(points[(size_t)hs_offset[0]+i][(size_t)hs_offset[1]+j] != check[(size_t)hs_offset[0]+i][(size_t)hs_offset[1]+j]) { H5_FAILED(); fprintf(stderr," Read different values than written.\n"); fprintf(stderr," At index %lu,%lu\n", (unsigned long)((size_t)hs_offset[0]+i), (unsigned long)((size_t)hs_offset[1]+j)); fprintf(stderr," At original: %d\n", (int)points[(size_t)hs_offset[0]+i][(size_t)hs_offset[1]+j]); fprintf(stderr," At returned: %d\n", (int)check[(size_t)hs_offset[0]+i][(size_t)hs_offset[1]+j]); goto error; } } } PASSED(); /* Save the data written to the file for later comparison when the file * is reopened for read test */ for(i=0; i<size[0]; i++) { for(j=0; j<size[1]; j++) { if(!HDstrcmp(name, DSET_DEFLATE_NAME)) { points_deflate[i][j] = points[i][j]; } else if(!HDstrcmp(name, DSET_DYNLIB1_NAME)) { points_dynlib1[i][j] = points[i][j]; } else if(!HDstrcmp(name, DSET_DYNLIB2_NAME)) { points_dynlib2[i][j] = points[i][j]; } } } /* Clean up objects used for this test */ if(H5Dclose (dataset) < 0) goto error; if(H5Sclose (sid) < 0) goto error; if(H5Pclose (dxpl) < 0) goto error; free (tconv_buf); return(0); error: if(tconv_buf) free (tconv_buf); return -1; }