Delay dataset layout copy to DCPL (#5537)

This commit is contained in:
Matt L
2025-06-20 11:02:55 -05:00
committed by GitHub
parent b89f178d71
commit 68bf564886
7 changed files with 375 additions and 26 deletions
+4 -3
View File
@@ -771,9 +771,7 @@ H5D__chunk_set_sizes(H5D_t *dset)
/* Sanity checks */
assert(dset);
/* Increment # of chunk dimensions, to account for datatype size as last element */
dset->shared->layout.u.chunk.ndims++;
assert(dset->shared->layout.u.chunk.ndims > 0);
/* Set the last dimension of the chunk size to the size of the datatype */
dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] =
@@ -838,6 +836,9 @@ H5D__chunk_construct(H5F_t H5_ATTR_UNUSED *f, H5D_t *dset)
if (dset->shared->layout.u.chunk.ndims != dset->shared->ndims)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimensionality of chunks doesn't match the dataspace");
/* Increment # of chunk dimensions, to account for datatype size as last element */
dset->shared->layout.u.chunk.ndims++;
/* Set chunk sizes */
if (H5D__chunk_set_sizes(dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "unable to set chunk sizes");
+72
View File
@@ -201,6 +201,8 @@ H5D__init_package(void)
H5D_def_dset.type_id = H5I_INVALID_HID;
H5D_def_dset.dapl_id = H5I_INVALID_HID;
H5D_def_dset.dcpl_id = H5I_INVALID_HID;
/* By default, do not copy layout immediately */
H5D_def_dset.layout_copied_to_dcpl = false;
/* Get the default dataset creation property list values and initialize the
* default dataset with them.
@@ -485,6 +487,8 @@ H5D__new(hid_t dcpl_id, hid_t dapl_id, bool creating, bool vl_type)
if (H5I_inc_ref(dcpl_id, false) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment default DCPL ID");
new_dset->dcpl_id = dcpl_id;
new_dset->layout_copied_to_dcpl = true;
} /* end if */
else {
/* Get the property list */
@@ -492,6 +496,10 @@ H5D__new(hid_t dcpl_id, hid_t dapl_id, bool creating, bool vl_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
new_dset->dcpl_id = H5P_copy_plist(plist, false);
/* If a specific DCPL was provided, then the dset's internal DCPL now has an accurate layout */
if (creating)
new_dset->layout_copied_to_dcpl = true;
} /* end else */
if (!vl_type && creating && dapl_id == H5P_DATASET_ACCESS_DEFAULT) {
@@ -1261,6 +1269,9 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "H5Z_has_optional_filter() failed");
if (false == ignore_filters) {
/* Layout only exists on DCPL at this point in dset creation */
assert(new_dset->shared->layout_copied_to_dcpl);
/* Check if the filters in the DCPL can be applied to this dataset */
if (H5Z_can_apply(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "I/O filters can't operate on this dataset");
@@ -3020,6 +3031,10 @@ H5D__check_filters(H5D_t *dataset)
if (fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
if (fill->fill_time == H5D_FILL_TIME_ALLOC ||
(fill->fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED)) {
/* Flush layout to DCPL before reading */
if (H5D_flush_layout_to_dcpl(dataset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to flush layout");
/* Filters must have encoding enabled. Ensure that all filters can be applied */
if (H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters");
@@ -3631,6 +3646,11 @@ H5D_get_create_plist(const H5D_t *dset)
if (NULL == (dcpl_plist = (H5P_genplist_t *)H5I_object(dset->shared->dcpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "can't get property list");
/* If necessary, flush virtual layout changes to the DCPL before copying */
if (H5D_flush_layout_to_dcpl(dset) < 0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't flush layout to DCPL");
}
/* Copy the creation property list */
if ((new_dcpl_id = H5P_copy_plist(dcpl_plist, true)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to copy the creation property list");
@@ -4057,3 +4077,55 @@ H5D_get_dcpl_id(const H5D_obj_create_t *d)
FUNC_LEAVE_NOAPI(d->dcpl_id);
} /* end H5D_get_dcpl_id() */
/*-------------------------------------------------------------------------
* Function: H5D_flush_layout_to_dcpl
*
* Purpose: Copy the dataset's creation-time layout to the internal DCPL,
* if this has not yet been done.
*
* Return: Success: non-negative
*
* Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
H5D_flush_layout_to_dcpl(const H5D_t *dset)
{
herr_t ret_value = SUCCEED;
H5P_genplist_t *dcpl = NULL;
bool ndims_modified = false;
FUNC_ENTER_NOAPI(FAIL)
if ((dcpl = H5P_object_verify(dset->shared->dcpl_id, H5P_DATASET_CREATE, true)) == NULL) {
HGOTO_ERROR(H5E_DATASET, H5E_BADID, FAIL, "invalid DCPL ID");
}
if (!dset->shared->layout_copied_to_dcpl) {
/* Don't modify default DCPL; short-circuit success */
if (H5P_is_default_plist(dset->shared->dcpl_id)) {
HGOTO_DONE(ret_value);
}
/* Adjust chunk dimensions to omit datatype size (in last dimension) for creation property */
if (H5D_CHUNKED == dset->shared->layout.type) {
dset->shared->layout.u.chunk.ndims--;
ndims_modified = true;
}
/* Copy layout property to DCPL from dataset */
if (H5P_set(dcpl, H5D_CRT_LAYOUT_NAME, (void *)&dset->shared->layout) < 0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout property");
}
}
done:
if (ret_value == SUCCEED)
dset->shared->layout_copied_to_dcpl = true;
if (ndims_modified)
dset->shared->layout.u.chunk.ndims++;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_flush_layout_to_dcpl() */
+4
View File
@@ -568,6 +568,10 @@ H5D__write(size_t count, H5D_dset_io_info_t *dset_info)
/* All filters in the DCPL must have encoding enabled. */
if (!dset_info[i].dset->shared->checked_filters) {
/* Flush layout to DCPL before readaing */
if (H5D_flush_layout_to_dcpl(dset_info[i].dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to flush layout");
if (H5Z_can_apply(dset_info[i].dset->shared->dcpl_id, dset_info[i].dset->shared->type_id) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters");
+17 -13
View File
@@ -570,11 +570,11 @@ done:
herr_t
H5D__layout_oh_read(H5D_t *dataset, hid_t dapl_id, H5P_genplist_t *plist)
{
htri_t msg_exists; /* Whether a particular type of message exists */
bool pline_copied = false; /* Flag to indicate that dcpl_cache.pline's message was copied */
bool layout_copied = false; /* Flag to indicate that layout message was copied */
bool efl_copied = false; /* Flag to indicate that the EFL message was copied */
herr_t ret_value = SUCCEED; /* Return value */
htri_t msg_exists; /* Whether a particular type of message exists */
bool pline_copied = false; /* Flag to indicate that dcpl_cache.pline's message was copied */
bool layout_copied_to_dset = false; /* Flag to indicate that layout message was copied */
bool efl_copied = false; /* Flag to indicate that the EFL message was copied */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -603,7 +603,7 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dapl_id, H5P_genplist_t *plist)
*/
if (NULL == H5O_msg_read(&(dataset->oloc), H5O_LAYOUT_ID, &(dataset->shared->layout)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message");
layout_copied = true;
layout_copied_to_dset = true;
/* Check for external file list message (which might not exist) */
if ((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_EFL_ID)) < 0)
@@ -630,13 +630,17 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dapl_id, H5P_genplist_t *plist)
(dataset->shared->layout.ops->init)(dataset->oloc.file, dataset, dapl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize layout information");
/* Adjust chunk dimensions to omit datatype size (in last dimension) for creation property */
if (H5D_CHUNKED == dataset->shared->layout.type)
dataset->shared->layout.u.chunk.ndims--;
#ifndef NDEBUG
/* Set invalid layout to detect erroneous usage */
H5O_layout_t error_layout;
error_layout.type = H5D_LAYOUT_ERROR;
error_layout.version = 0;
error_layout.ops = NULL;
error_layout.storage.type = H5D_LAYOUT_ERROR;
/* Copy layout to the DCPL */
if (H5P_set(plist, H5D_CRT_LAYOUT_NAME, &dataset->shared->layout) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout");
if (H5P_poke(plist, H5D_CRT_LAYOUT_NAME, &error_layout) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to setup placeholder layout");
#endif
/* Set chunk sizes */
if (H5D_CHUNKED == dataset->shared->layout.type)
@@ -648,7 +652,7 @@ done:
if (pline_copied)
if (H5O_msg_reset(H5O_PLINE_ID, &dataset->shared->dcpl_cache.pline) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset pipeline info");
if (layout_copied)
if (layout_copied_to_dset)
if (H5O_msg_reset(H5O_LAYOUT_ID, &dataset->shared->layout) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset layout info");
if (efl_copied)
+11 -10
View File
@@ -531,16 +531,17 @@ typedef struct H5D_rdcdc_t {
* there will be two IDs and two H5D_t structs, both sharing one H5D_shared_t.
*/
struct H5D_shared_t {
size_t fo_count; /* Reference count */
bool closing; /* Flag to indicate dataset is closing */
hid_t type_id; /* ID for dataset's datatype */
H5T_t *type; /* Datatype for this dataset */
H5S_t *space; /* Dataspace of this dataset */
hid_t dcpl_id; /* Dataset creation property id */
hid_t dapl_id; /* Dataset access property id */
H5D_dcpl_cache_t dcpl_cache; /* Cached DCPL values */
H5O_layout_t layout; /* Data layout */
bool checked_filters; /* true if dataset passes can_apply check */
size_t fo_count; /* Reference count */
bool closing; /* Flag to indicate dataset is closing */
hid_t type_id; /* ID for dataset's datatype */
H5T_t *type; /* Datatype for this dataset */
H5S_t *space; /* Dataspace of this dataset */
hid_t dcpl_id; /* Dataset creation property id */
hid_t dapl_id; /* Dataset access property id */
H5D_dcpl_cache_t dcpl_cache; /* Cached DCPL values */
H5O_layout_t layout; /* Data layout */
bool layout_copied_to_dcpl; /* Whether the layout has change not present in the DCPL */
bool checked_filters; /* true if dataset passes can_apply check */
/* Cached dataspace info */
unsigned ndims; /* The dataset's dataspace rank */
+1
View File
@@ -179,6 +179,7 @@ H5_DLL herr_t H5D_flush_all(H5F_t *f);
H5_DLL hid_t H5D_get_create_plist(const H5D_t *dset);
H5_DLL hid_t H5D_get_access_plist(const H5D_t *dset);
H5_DLL hid_t H5D_get_dcpl_id(const H5D_obj_create_t *d);
H5_DLL herr_t H5D_flush_layout_to_dcpl(const H5D_t *dset);
/* Functions that operate on chunked storage */
H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, bool reset_addr);
+266
View File
@@ -300,6 +300,14 @@ const char *OLD_FILENAME[] = {
"btree_idx_1_8.h5" /* 1.8 HDF5 file */
};
/* Declarations for test_dcpl_layout_caching */
#define DCPL_LAYOUT_FILENAME "dcpl_layout_test.h5"
#define DCPL_LAYOUT_DSETNAME "dcpl_layout_dset"
#define DCPL_LAYOUT_RANK 2
#define DCPL_LAYOUT_DIM1 10
#define DCPL_LAYOUT_DIM2 10
#define DCPL_LAYOUT_NUM_SRC_DSETS 2
/* Local prototypes for filter functions */
static size_t filter_bogus(unsigned int flags, size_t cd_nelmts, const unsigned int *cd_values, size_t nbytes,
size_t *buf_size, void **buf);
@@ -15887,6 +15895,258 @@ error:
return -1;
} /* end test_downsize_vlen_scalar_dataset() */
/*-------------------------------------------------------------------------
* Function: test_dcpl_layout_caching
*
* Purpose: Ensure that layouts are not copied to DCPLs until necessary.
*
* Return: Success: 0
* Failure: 1
*-------------------------------------------------------------------------
*/
static int
test_dcpl_layout_caching(H5D_layout_t layout_type)
{
hid_t file_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t type_id = H5I_INVALID_HID;
hid_t dcpl_id = H5I_INVALID_HID;
H5O_layout_t layout;
H5O_layout_t default_layout;
H5D_t *dset_int = NULL;
H5P_genplist_t *dcpl_int = NULL;
H5P_genplist_t *default_dcpl_int = NULL;
hsize_t dims[DCPL_LAYOUT_RANK] = {DCPL_LAYOUT_DIM1, DCPL_LAYOUT_DIM2};
hsize_t cdims[DCPL_LAYOUT_RANK] = {DCPL_LAYOUT_DIM1 / 2, DCPL_LAYOUT_DIM2 / 2};
hsize_t src_dims[DCPL_LAYOUT_RANK] = {DCPL_LAYOUT_DIM1 / DCPL_LAYOUT_NUM_SRC_DSETS, DCPL_LAYOUT_DIM2};
hid_t src_space_id = H5I_INVALID_HID;
hid_t src_files[DCPL_LAYOUT_NUM_SRC_DSETS];
hid_t src_dsets[DCPL_LAYOUT_NUM_SRC_DSETS];
const char *layout_msg = NULL;
char test_str[FILENAME_BUF_SIZE];
switch (layout_type) {
case (H5D_COMPACT):
layout_msg = "compact layout";
break;
case (H5D_CONTIGUOUS):
layout_msg = "contiguous layout";
break;
case (H5D_CHUNKED):
layout_msg = "chunked layout";
break;
case (H5D_VIRTUAL):
layout_msg = "virtual layout";
break;
default:
TEST_ERROR;
break;
}
snprintf(test_str, sizeof(test_str), "delayed DCPL layout copy for %s", layout_msg);
TESTING(test_str);
if ((file_id = H5Fcreate(DCPL_LAYOUT_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((type_id = H5Tcopy(H5T_NATIVE_INT)) < 0)
TEST_ERROR;
if ((space_id = H5Screate_simple(DCPL_LAYOUT_RANK, dims, NULL)) < 0)
TEST_ERROR;
if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
TEST_ERROR;
/* Set up dataset */
switch (layout_type) {
case (H5D_COMPACT):
if (H5Pset_layout(dcpl_id, H5D_COMPACT) < 0)
TEST_ERROR;
if ((dset_id = H5Dcreate2(file_id, DCPL_LAYOUT_DSETNAME, type_id, space_id, H5P_DEFAULT, dcpl_id,
H5P_DEFAULT)) < 0)
TEST_ERROR;
break;
case (H5D_CONTIGUOUS):
if (H5Pset_layout(dcpl_id, H5D_CONTIGUOUS) < 0)
TEST_ERROR;
if ((dset_id = H5Dcreate2(file_id, DCPL_LAYOUT_DSETNAME, type_id, space_id, H5P_DEFAULT, dcpl_id,
H5P_DEFAULT)) < 0)
TEST_ERROR;
break;
case (H5D_CHUNKED):
if (H5Pset_chunk(dcpl_id, DCPL_LAYOUT_RANK, cdims) < 0)
TEST_ERROR;
if ((dset_id = H5Dcreate2(file_id, DCPL_LAYOUT_DSETNAME, type_id, space_id, H5P_DEFAULT, dcpl_id,
H5P_DEFAULT)) < 0)
TEST_ERROR;
break;
case (H5D_VIRTUAL):
if ((src_space_id = H5Screate_simple(DCPL_LAYOUT_RANK, src_dims, NULL)) < 0)
TEST_ERROR;
/* Create source files and datasets */
for (int i = 0; i < DCPL_LAYOUT_NUM_SRC_DSETS; i++) {
char src_fname[FILENAME_BUF_SIZE];
char src_dname[FILENAME_BUF_SIZE];
if (snprintf(src_fname, FILENAME_BUF_SIZE, "%s%s%d.h5", DCPL_LAYOUT_FILENAME, "_src", i) >=
FILENAME_BUF_SIZE)
TEST_ERROR;
if (snprintf(src_dname, FILENAME_BUF_SIZE, "%s%s%d", DCPL_LAYOUT_DSETNAME, "_src", i) >=
FILENAME_BUF_SIZE)
TEST_ERROR;
if ((src_files[i] = H5Fcreate(src_fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((src_dsets[i] = H5Dcreate2(src_files[i], src_dname, type_id, src_space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
/* Select entire source */
if (H5Sselect_all(src_space_id) < 0)
TEST_ERROR;
/* Destination selection */
hsize_t dest_sel_start[DCPL_LAYOUT_RANK] = {
(hsize_t)i * (DCPL_LAYOUT_DIM1 / DCPL_LAYOUT_NUM_SRC_DSETS), 0};
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, dest_sel_start, NULL, src_dims, NULL) < 0)
TEST_ERROR;
/* Map destination selection to src selection */
if ((H5Pset_virtual(dcpl_id, space_id, src_fname, src_dname, src_space_id)) < 0)
TEST_ERROR;
}
/* Create virtual dataset */
if (H5Sselect_all(space_id) < 0)
TEST_ERROR;
if ((dset_id = H5Dcreate2(file_id, DCPL_LAYOUT_DSETNAME, type_id, space_id, H5P_DEFAULT, dcpl_id,
H5P_DEFAULT)) < 0)
TEST_ERROR;
break;
default:
TEST_ERROR;
break;
}
/* After dataset is closed and re-opened, internal DCPL should not contain copied layout */
if (H5Dclose(dset_id) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;
if ((file_id = H5Fopen(DCPL_LAYOUT_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((dset_id = H5Dopen2(file_id, DCPL_LAYOUT_DSETNAME, H5P_DEFAULT)) < 0)
TEST_ERROR;
/* Verify that internal DCPL of dataset is not yet copied */
if ((dset_int = H5VL_object(dset_id)) == NULL)
TEST_ERROR;
/* Copy flag should be false */
if (dset_int->shared->layout_copied_to_dcpl)
TEST_ERROR;
/* Access layout through internal routines to avoid triggering layout copy */
if ((dcpl_int = H5P_object_verify(dset_int->shared->dcpl_id, H5P_DATASET_CREATE, false)) == NULL)
TEST_ERROR;
if (H5P_peek(dcpl_int, H5D_CRT_LAYOUT_NAME, &layout) < 0)
TEST_ERROR;
if ((default_dcpl_int = H5P_object_verify(H5P_DATASET_CREATE_DEFAULT, H5P_DATASET_CREATE, true)) == NULL)
TEST_ERROR;
if (H5P_peek(default_dcpl_int, H5D_CRT_LAYOUT_NAME, &default_layout) < 0)
TEST_ERROR;
#ifdef NDEBUG
/* When NDEBUG is enabled, layout stored on internal DCPL should be equivalent to the default DCPL layout
*/
if (memcmp(&layout, &default_layout, sizeof(H5O_layout_t)) != 0)
TEST_ERROR;
#else /* NDEBUG disabled */
/* When NDEBUG is disabled, the internal layout should have an invalid layout to detect bad accesses */
if (layout.type != H5D_LAYOUT_ERROR)
TEST_ERROR;
#endif /* NDEBUG */
/* After a user request for DCPL, internal DCPL should contain updated layout */
if (H5Pclose(dcpl_id) < 0)
TEST_ERROR;
if ((dcpl_id = H5Dget_create_plist(dset_id)) < 0)
TEST_ERROR;
if ((dcpl_int = H5P_object_verify(dset_int->shared->dcpl_id, H5P_DATASET_CREATE, false)) == NULL)
TEST_ERROR;
if (H5P_peek(dcpl_int, H5D_CRT_LAYOUT_NAME, &layout) < 0)
TEST_ERROR;
if (layout.type != layout_type)
TEST_ERROR;
/* Clean up */
if (H5Fclose(file_id) < 0)
TEST_ERROR;
if (H5Pclose(dcpl_id) < 0)
TEST_ERROR;
if (H5Tclose(type_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Dclose(dset_id) < 0)
TEST_ERROR;
if (layout_type == H5D_VIRTUAL) {
for (int i = 0; i < DCPL_LAYOUT_NUM_SRC_DSETS; i++) {
if (H5Fclose(src_files[i]) < 0)
TEST_ERROR;
if (H5Dclose(src_dsets[i]) < 0)
TEST_ERROR;
}
}
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Fclose(file_id);
H5Pclose(dcpl_id);
H5Tclose(type_id);
H5Sclose(space_id);
H5Dclose(dset_id);
for (int i = 0; i < DCPL_LAYOUT_NUM_SRC_DSETS; i++) {
H5Fclose(src_files[i]);
H5Dclose(src_dsets[i]);
}
}
H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* Function: main
*
@@ -16166,6 +16426,12 @@ main(void)
/* Verify symbol table messages are cached */
nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);
/* Verify that DCPL layout is not copied immediately on open */
nerrors += (test_dcpl_layout_caching(H5D_COMPACT) < 0 ? 1 : 0);
nerrors += (test_dcpl_layout_caching(H5D_CONTIGUOUS) < 0 ? 1 : 0);
nerrors += (test_dcpl_layout_caching(H5D_CHUNKED) < 0 ? 1 : 0);
nerrors += (test_dcpl_layout_caching(H5D_VIRTUAL) < 0 ? 1 : 0);
if (nerrors)
goto error;
printf("All dataset tests passed.\n");