Add initial version of HDF5 API tests (#2877)

This commit is contained in:
jhendersonHDF
2023-05-02 12:52:39 -07:00
committed by GitHub
parent 41fd8e66a9
commit f8a1b3ceec
200 changed files with 212642 additions and 49 deletions
+279
View File
@@ -0,0 +1,279 @@
# Copyright by The HDF Group.
# 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://www.hdfgroup.org/licenses.
# If you do not have access to either file, you may request a copy from
# help@hdfgroup.org.
#
#------------------------------------------------------------------------------
# Set module path
#------------------------------------------------------------------------------
set(HDF5_TEST_API_CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${HDF5_TEST_API_CMAKE_MODULE_PATH})
#------------------------------------------------------------------------------
# Setup for API tests
#------------------------------------------------------------------------------
# Ported HDF5 tests
set (HDF5_API_PAR_TESTS_EXTRA
t_bigio
t_pshutdown
t_shapesame
testphdf5
)
# List of files generated by the HDF5 API tests which
# should be cleaned up in case the test failed to remove
# them
set (HDF5_API_PAR_TESTS_FILES
H5_api_test_parallel.h5
H5_api_async_test_parallel.h5
H5_api_async_test_parallel_0.h5
H5_api_async_test_parallel_1.h5
H5_api_async_test_parallel_2.h5
H5_api_async_test_parallel_3.h5
H5_api_async_test_parallel_4.h5
test_file_parallel.h5
split_comm_file.h5
)
#-----------------------------------------------------------------------------
# Build the main API test executable
#-----------------------------------------------------------------------------
foreach (api_test ${HDF5_API_TESTS})
set (HDF5_API_PAR_TEST_SRCS
${HDF5_API_PAR_TEST_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/H5_api_${api_test}_test_parallel.c
)
endforeach ()
set (HDF5_API_PAR_TEST_SRCS
${HDF5_API_PAR_TEST_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/H5_api_test_parallel.c
${HDF5_TEST_API_SRC_DIR}/H5_api_test_util.c
)
add_executable (h5_api_test_parallel ${HDF5_API_PAR_TEST_SRCS})
target_include_directories (
h5_api_test_parallel
PRIVATE
"${HDF5_SRC_INCLUDE_DIRS}"
"${HDF5_TEST_PAR_DIR}"
"${HDF5_TEST_API_SRC_DIR}"
"${HDF5_TEST_API_PAR_SRC_DIR}"
"${HDF5_SRC_BINARY_DIR}"
"${HDF5_TEST_BINARY_DIR}"
"${HDF5_TEST_API_SRC_DIR}"
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>"
)
target_compile_options (
h5_api_test_parallel
PRIVATE
"${HDF5_CMAKE_C_FLAGS}"
)
target_compile_definitions (
h5_api_test_parallel
PRIVATE
$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>
)
if (NOT BUILD_SHARED_LIBS)
TARGET_C_PROPERTIES (h5_api_test_parallel STATIC)
target_link_libraries (
h5_api_test_parallel
PRIVATE
${HDF5_TEST_LIB_TARGET}
${HDF5_LIB_TARGET}
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPI::MPI_C>"
)
else ()
TARGET_C_PROPERTIES (h5_api_test_parallel SHARED)
target_link_libraries (
h5_api_test_parallel
PRIVATE
${HDF5_TEST_LIBSH_TARGET}
${HDF5_LIBSH_TARGET}
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPI::MPI_C>"
)
endif ()
set_target_properties (
h5_api_test_parallel
PROPERTIES
FOLDER test/par/API
)
# Add Target to clang-format
if (HDF5_ENABLE_FORMATTERS)
clang_format (HDF5_TEST_h5_api_test_parallel_FORMAT h5_api_test_parallel)
endif ()
#-----------------------------------------------------------------------------
# Build the ported HDF5 test executables
#-----------------------------------------------------------------------------
foreach (api_test_extra ${HDF5_API_PAR_TESTS_EXTRA})
unset (HDF5_API_PAR_TEST_EXTRA_SRCS)
set (HDF5_API_PAR_TEST_EXTRA_SRCS
${HDF5_API_PAR_TEST_EXTRA_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/${api_test_extra}.c
)
if (${api_test_extra} STREQUAL "testphdf5")
set (HDF5_API_PAR_TEST_EXTRA_SRCS
${HDF5_API_PAR_TEST_EXTRA_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/t_ph5basic.c
${CMAKE_CURRENT_SOURCE_DIR}/t_file.c
${CMAKE_CURRENT_SOURCE_DIR}/t_dset.c
${CMAKE_CURRENT_SOURCE_DIR}/t_mdset.c
${CMAKE_CURRENT_SOURCE_DIR}/t_coll_chunk.c
${CMAKE_CURRENT_SOURCE_DIR}/t_span_tree.c
${CMAKE_CURRENT_SOURCE_DIR}/t_prop.c
${CMAKE_CURRENT_SOURCE_DIR}/t_file_image.c
${CMAKE_CURRENT_SOURCE_DIR}/t_coll_md_read.c
${CMAKE_CURRENT_SOURCE_DIR}/t_chunk_alloc.c
${CMAKE_CURRENT_SOURCE_DIR}/t_filter_read.c
)
endif ()
add_executable (h5_api_test_parallel_${api_test_extra} ${HDF5_API_PAR_TEST_EXTRA_SRCS})
target_include_directories (
h5_api_test_parallel_${api_test_extra}
PRIVATE
"${HDF5_SRC_INCLUDE_DIRS}"
"${HDF5_TEST_PAR_DIR}"
"${HDF5_TEST_API_SRC_DIR}"
"${HDF5_TEST_API_PAR_SRC_DIR}"
"${HDF5_SRC_BINARY_DIR}"
"${HDF5_TEST_BINARY_DIR}"
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>"
)
target_compile_options (
h5_api_test_parallel_${api_test_extra}
PRIVATE
"${HDF5_CMAKE_C_FLAGS}"
)
target_compile_definitions (
h5_api_test_parallel_${api_test_extra}
PRIVATE
$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>
)
if (NOT BUILD_SHARED_LIBS)
TARGET_C_PROPERTIES (h5_api_test_parallel_${api_test_extra} STATIC)
target_link_libraries (
h5_api_test_parallel_${api_test_extra}
PRIVATE
${HDF5_TEST_LIB_TARGET}
${HDF5_LIB_TARGET}
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPI::MPI_C>"
)
else ()
TARGET_C_PROPERTIES (h5_api_test_parallel_${api_test_extra} SHARED)
target_link_libraries (
h5_api_test_parallel_${api_test_extra}
PRIVATE
${HDF5_TEST_LIBSH_TARGET}
${HDF5_LIBSH_TARGET}
"$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPI::MPI_C>"
)
endif ()
set_target_properties (
h5_api_test_parallel_${api_test_extra}
PROPERTIES
FOLDER test/par/API
)
# Add Target to clang-format
if (HDF5_ENABLE_FORMATTERS)
clang_format (HDF5_TEST_h5_api_test_parallel_${api_test_extra}_FORMAT h5_api_test_parallel_${api_test_extra})
endif ()
endforeach ()
#-----------------------------------------------------------------------------
# Add tests if HDF5 parallel testing is enabled
#-----------------------------------------------------------------------------
if (HDF5_TEST_PARALLEL)
if (HDF5_TEST_API_ENABLE_DRIVER)
if ("${HDF5_TEST_API_SERVER}" STREQUAL "")
message (FATAL_ERROR "Please set HDF5_TEST_API_SERVER to point to a server executable for the test driver program.")
endif ()
# Driver options
if (HDF5_TEST_API_SERVER_ALLOW_ERRORS)
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS --allow-server-errors)
endif ()
if (HDF5_TEST_API_CLIENT_HELPER)
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS ${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
--client-helper ${HDF5_TEST_API_CLIENT_HELPER}
)
endif ()
if (HDF5_TEST_API_CLIENT_INIT)
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS ${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
--client-init ${HDF5_TEST_API_CLIENT_INIT}
)
endif ()
set(last_api_test "")
foreach (api_test ${HDF5_API_TESTS})
add_test (
NAME "h5_api_test_parallel_${api_test}"
COMMAND $<TARGET_FILE:h5_api_test_driver>
--server ${HDF5_TEST_API_SERVER}
--client $<TARGET_FILE:h5_api_test_parallel> "${api_test}"
--serial
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
)
set_tests_properties("h5_api_test_parallel_${api_test}" PROPERTIES DEPENDS "${last_api_test}")
set(last_api_test "h5_api_test_parallel_${api_test}")
endforeach ()
foreach (hdf5_test ${HDF5_API_PAR_TESTS_EXTRA})
add_test (
NAME "h5_api_test_parallel_${hdf5_test}"
COMMAND $<TARGET_FILE:h5_api_test_driver>
--server ${HDF5_TEST_API_SERVER}
--client $<TARGET_FILE:h5_api_test_parallel_${hdf5_test}>
--serial
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
)
endforeach ()
# Hook external tests to same test suite
foreach (ext_api_test ${HDF5_API_EXT_PARALLEL_TESTS})
add_test (
NAME "h5_api_ext_test_parallel_${ext_api_test}"
COMMAND $<TARGET_FILE:h5_api_test_driver>
--server ${HDF5_TEST_API_SERVER}
--client $<TARGET_FILE:${ext_api_test}>
--serial
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
)
endforeach ()
else ()
set(last_api_test "")
foreach (api_test ${HDF5_API_TESTS})
add_test (
NAME "h5_api_test_parallel_${api_test}"
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
${MPIEXEC_PREFLAGS} $<TARGET_FILE:h5_api_test_parallel> "${api_test}"
${MPIEXEC_POSTFLAGS}
)
set_tests_properties("h5_api_test_parallel_${api_test}" PROPERTIES DEPENDS "${last_api_test}")
set(last_api_test "h5_api_test_parallel_${api_test}")
endforeach ()
foreach (hdf5_test ${HDF5_API_PAR_TESTS_EXTRA})
add_test (
NAME "h5_api_test_parallel_${hdf5_test}"
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
${MPIEXEC_PREFLAGS} $<TARGET_FILE:h5_api_test_parallel_${hdf5_test}>
${MPIEXEC_POSTFLAGS}
)
endforeach ()
endif ()
endif ()
+3668
View File
@@ -0,0 +1,3668 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_async_test_parallel.h"
#ifdef H5ESpublic_H
static int test_one_dataset_io(void);
static int test_multi_dataset_io(void);
static int test_multi_file_dataset_io(void);
static int test_multi_file_grp_dset_io(void);
static int test_set_extent(void);
static int test_attribute_exists(void);
static int test_attribute_io(void);
static int test_attribute_io_tconv(void);
static int test_attribute_io_compound(void);
static int test_group(void);
static int test_link(void);
static int test_ocopy_orefresh(void);
static int test_file_reopen(void);
/*
* The array of parallel async tests to be performed.
*/
static int (*par_async_tests[])(void) = {
test_one_dataset_io,
test_multi_dataset_io,
test_multi_file_dataset_io,
test_multi_file_grp_dset_io,
test_set_extent,
test_attribute_exists,
test_attribute_io,
test_attribute_io_tconv,
test_attribute_io_compound,
test_group,
test_link,
test_ocopy_orefresh,
test_file_reopen,
};
hbool_t coll_metadata_read = TRUE;
/* Highest "printf" file created (starting at 0) */
int max_printf_file = -1;
/*
* Create file and dataset. Each rank writes to a portion
* of the dataset.
*/
#define ONE_DATASET_IO_TEST_SPACE_RANK 2
static int
test_one_dataset_io(void)
{
hsize_t *dims = NULL;
hsize_t start[ONE_DATASET_IO_TEST_SPACE_RANK];
hsize_t stride[ONE_DATASET_IO_TEST_SPACE_RANK];
hsize_t count[ONE_DATASET_IO_TEST_SPACE_RANK];
hsize_t block[ONE_DATASET_IO_TEST_SPACE_RANK];
hbool_t op_failed = false;
hbool_t is_native_vol = false;
size_t i, data_size, num_in_progress;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
int *write_buf = NULL;
int *read_buf = NULL;
TESTING_MULTIPART("single dataset I/O")
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(
" API functions for basic file, dataset, or flush aren't supported with this connector\n");
}
return 0;
}
TESTING_2("test setup");
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(ONE_DATASET_IO_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
if ((space_id = H5Screate_simple(ONE_DATASET_IO_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Create file asynchronously */
if ((file_id = H5Fcreate_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(file_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers - first dimension is skipped in calculation */
for (i = 1, data_size = 1; i < ONE_DATASET_IO_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset read\n");
TEST_ERROR;
}
/* Select this rank's portion of the dataspace */
for (i = 0; i < ONE_DATASET_IO_TEST_SPACE_RANK; i++) {
if (i == 0) {
start[i] = (hsize_t)mpi_rank;
block[i] = 1;
}
else {
start[i] = 0;
block[i] = dims[i];
}
stride[i] = 1;
count[i] = 1;
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Setup memory space for write_buf */
{
hsize_t mdims[] = {data_size / sizeof(int)};
if ((mspace_id = H5Screate_simple(1, mdims, NULL)) < 0) {
H5_FAILED();
HDprintf(" couldn't create memory dataspace\n");
goto error;
}
}
PASSED();
BEGIN_MULTIPART
{
PART_BEGIN(single_dset_eswait)
{
TESTING_2("synchronization using H5ESwait()");
/* Initialize write_buf */
for (i = 0; i < data_size / sizeof(int); i++)
((int *)write_buf)[i] = mpi_rank;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, write_buf, es_id) <
0)
PART_TEST_ERROR(single_dset_eswait);
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(single_dset_eswait);
if (op_failed)
PART_TEST_ERROR(single_dset_eswait);
/* Read the dataset asynchronously */
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, read_buf, es_id) < 0)
PART_TEST_ERROR(single_dset_eswait);
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(single_dset_eswait);
if (op_failed)
PART_TEST_ERROR(single_dset_eswait);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(single_dset_eswait);
} /* end if */
PASSED();
}
PART_END(single_dset_eswait);
PART_BEGIN(single_dset_dclose)
{
TESTING_2("synchronization using H5Dclose()");
/* Initialize write_buf */
for (i = 0; i < data_size / sizeof(int); i++)
((int *)write_buf)[i] = (int)i;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, write_buf, es_id) <
0)
PART_TEST_ERROR(single_dset_dclose);
/* Close the dataset synchronously */
if (H5Dclose(dset_id) < 0)
PART_TEST_ERROR(single_dset_dclose);
/* Re-open the dataset asynchronously */
if ((dset_id = H5Dopen_async(file_id, "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(single_dset_dclose);
/* Read the dataset asynchronously */
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, read_buf, es_id) < 0)
PART_TEST_ERROR(single_dset_dclose);
/* Close the dataset synchronously */
if (H5Dclose(dset_id) < 0)
PART_TEST_ERROR(single_dset_dclose);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(single_dset_dclose);
} /* end if */
/* Re-open the dataset asynchronously */
if ((dset_id = H5Dopen_async(file_id, "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(single_dset_dclose);
PASSED();
}
PART_END(single_dset_dclose);
PART_BEGIN(single_dset_dflush)
{
TESTING_2("synchronization using H5Oflush_async()");
/* Initialize write_buf */
for (i = 0; i < data_size / sizeof(int); i++)
((int *)write_buf)[i] = 10 * (int)i;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, write_buf, es_id) <
0)
PART_TEST_ERROR(single_dset_dflush);
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. Skip this
* function because it isn't supported for the native vol in parallel. */
if (!is_native_vol && H5Oflush_async(dset_id, es_id) < 0)
PART_TEST_ERROR(single_dset_dflush);
/* Read the dataset asynchronously */
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, read_buf, es_id) < 0)
PART_TEST_ERROR(single_dset_dflush);
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(single_dset_dflush);
if (op_failed)
PART_TEST_ERROR(single_dset_dflush);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(single_dset_dflush);
} /* end if */
PASSED();
}
PART_END(single_dset_dflush);
PART_BEGIN(single_dset_fclose)
{
TESTING_2("synchronization using H5Fclose()");
/* Initialize write_buf */
for (i = 0; i < data_size / sizeof(int); i++)
((int *)write_buf)[i] = (int)i + 5;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, write_buf, es_id) <
0)
PART_TEST_ERROR(single_dset_fclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Close the file synchronously */
if (H5Fclose(file_id) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Reopen the file asynchronously. */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDONLY, fapl_id, es_id)) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Re-open the dataset asynchronously */
if ((dset_id = H5Dopen_async(file_id, "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Read the dataset asynchronously */
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, read_buf, es_id) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Close the file synchronously */
if (H5Fclose(file_id) < 0)
PART_TEST_ERROR(single_dset_fclose);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(single_dset_fclose);
} /* end if */
PASSED();
}
PART_END(single_dset_fclose);
}
END_MULTIPART;
TESTING_2("test cleanup");
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Sclose(mspace_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Sclose(mspace_id);
H5Dclose(dset_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef ONE_DATASET_IO_TEST_SPACE_RANK
/*
* Create file and multiple datasets. Each rank writes to a
* portion of each dataset and reads back their portion of
* each dataset.
*/
#define MULTI_DATASET_IO_TEST_SPACE_RANK 2
#define MULTI_DATASET_IO_TEST_NDSETS 5
static int
test_multi_dataset_io(void)
{
hsize_t *dims = NULL;
hsize_t start[MULTI_DATASET_IO_TEST_SPACE_RANK];
hsize_t stride[MULTI_DATASET_IO_TEST_SPACE_RANK];
hsize_t count[MULTI_DATASET_IO_TEST_SPACE_RANK];
hsize_t block[MULTI_DATASET_IO_TEST_SPACE_RANK];
hbool_t op_failed;
size_t i, j, data_size, num_in_progress;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id[MULTI_DATASET_IO_TEST_NDSETS] = {H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
H5I_INVALID_HID, H5I_INVALID_HID};
hid_t space_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
char dset_name[32];
int *write_buf = NULL;
int *read_buf = NULL;
TESTING_MULTIPART("multi dataset I/O")
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(
" API functions for basic file, dataset, or flush aren't supported with this connector\n");
}
return 0;
}
TESTING_2("test setup");
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(MULTI_DATASET_IO_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(MULTI_DATASET_IO_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Create file asynchronously */
if ((file_id = H5Fcreate_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers - first dimension is skipped in calculation */
for (i = 1, data_size = 1; i < MULTI_DATASET_IO_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
data_size *= MULTI_DATASET_IO_TEST_NDSETS;
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset read\n");
TEST_ERROR;
}
/* Select this rank's portion of the dataspace */
for (i = 0; i < MULTI_DATASET_IO_TEST_SPACE_RANK; i++) {
if (i == 0) {
start[i] = (hsize_t)mpi_rank;
block[i] = 1;
}
else {
start[i] = 0;
block[i] = dims[i];
}
stride[i] = 1;
count[i] = 1;
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Setup memory space for write_buf */
{
hsize_t mdims[] = {data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int)};
if ((mspace_id = H5Screate_simple(1, mdims, NULL)) < 0) {
H5_FAILED();
HDprintf(" couldn't create memory dataspace\n");
goto error;
}
}
PASSED();
BEGIN_MULTIPART
{
PART_BEGIN(multi_dset_open)
{
size_t buf_start_idx;
TESTING_2("keeping datasets open");
/* Loop over datasets */
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++) {
size_t buf_end_idx;
/* Set dataset name */
sprintf(dset_name, "dset%d", (int)i);
/* Create the dataset asynchronously */
if ((dset_id[i] = H5Dcreate_async(file_id, dset_name, H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_dset_open);
/* Initialize write_buf. Must use a new slice of write_buf for
* each dset since we can't overwrite the buffers until I/O is done. */
buf_start_idx = i * (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id[i], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_dset_open);
} /* end for */
/* Flush the file asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
PART_TEST_ERROR(multi_dset_open);
/* Loop over datasets */
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++) {
buf_start_idx = i * (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
/* Read the dataset asynchronously */
if (H5Dread_async(dset_id[i], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_dset_open);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_dset_open);
if (op_failed)
PART_TEST_ERROR(multi_dset_open);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_dset_open);
} /* end if */
/* Close the datasets */
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++)
if (H5Dclose(dset_id[i]) < 0)
PART_TEST_ERROR(multi_dset_open);
PASSED();
}
PART_END(multi_dset_open);
PART_BEGIN(multi_dset_close)
{
size_t buf_start_idx;
TESTING_2("closing datasets between I/O");
/* Loop over datasets */
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++) {
size_t buf_end_idx;
/* Set dataset name */
sprintf(dset_name, "dset%d", (int)i);
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id, dset_name, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_dset_close);
/* Initialize write_buf. */
buf_start_idx = i * (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank * 10;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_dset_close);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_dset_close);
} /* end for */
/* Flush the file asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
PART_TEST_ERROR(multi_dset_close);
/* Loop over datasets */
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++) {
/* Set dataset name */
sprintf(dset_name, "dset%d", (int)i);
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id, dset_name, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_dset_close);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_DATASET_IO_TEST_NDSETS / sizeof(int));
if (H5Dread_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_dset_close);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_dset_close);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_dset_close);
if (op_failed)
PART_TEST_ERROR(multi_dset_close);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_dset_close);
} /* end if */
PASSED();
}
PART_END(multi_dset_close);
}
END_MULTIPART;
TESTING_2("test cleanup");
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Sclose(mspace_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Sclose(mspace_id);
for (i = 0; i < MULTI_DATASET_IO_TEST_NDSETS; i++)
H5Dclose(dset_id[i]);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef MULTI_DATASET_IO_TEST_SPACE_RANK
#undef MULTI_DATASET_IO_TEST_NDSETS
/*
* Create multiple files, each with a single dataset. Each rank writes
* to a portion of each dataset and reads from a portion of each dataset.
*/
#define MULTI_FILE_DATASET_IO_TEST_SPACE_RANK 2
#define MULTI_FILE_DATASET_IO_TEST_NFILES 5
static int
test_multi_file_dataset_io(void)
{
hsize_t *dims = NULL;
hsize_t start[MULTI_FILE_DATASET_IO_TEST_SPACE_RANK];
hsize_t stride[MULTI_FILE_DATASET_IO_TEST_SPACE_RANK];
hsize_t count[MULTI_FILE_DATASET_IO_TEST_SPACE_RANK];
hsize_t block[MULTI_FILE_DATASET_IO_TEST_SPACE_RANK];
hbool_t op_failed = false;
hbool_t is_native_vol = false;
size_t i, j, data_size, num_in_progress;
hid_t fapl_id = H5I_INVALID_HID;
hid_t file_id[MULTI_FILE_DATASET_IO_TEST_NFILES] = {H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
H5I_INVALID_HID, H5I_INVALID_HID};
hid_t dset_id[MULTI_FILE_DATASET_IO_TEST_NFILES] = {H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
H5I_INVALID_HID, H5I_INVALID_HID};
hid_t space_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
char file_name[32];
int *write_buf = NULL;
int *read_buf = NULL;
TESTING_MULTIPART("multi file dataset I/O")
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(
" API functions for basic file, dataset, or flush aren't supported with this connector\n");
}
return 0;
}
TESTING_2("test setup");
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(MULTI_FILE_DATASET_IO_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(MULTI_FILE_DATASET_IO_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Calculate size of data buffers - first dimension is skipped in calculation */
for (i = 1, data_size = 1; i < MULTI_FILE_DATASET_IO_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
data_size *= MULTI_FILE_DATASET_IO_TEST_NFILES;
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset read\n");
TEST_ERROR;
}
/* Select this rank's portion of the dataspace */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_SPACE_RANK; i++) {
if (i == 0) {
start[i] = (hsize_t)mpi_rank;
block[i] = 1;
}
else {
start[i] = 0;
block[i] = dims[i];
}
stride[i] = 1;
count[i] = 1;
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Setup memory space for write_buf */
{
hsize_t mdims[] = {data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int)};
if ((mspace_id = H5Screate_simple(1, mdims, NULL)) < 0) {
H5_FAILED();
HDprintf(" couldn't create memory dataspace\n");
goto error;
}
}
PASSED();
BEGIN_MULTIPART
{
PART_BEGIN(multi_file_dset_open)
{
size_t buf_start_idx;
TESTING_2("keeping files and datasets open");
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
size_t buf_end_idx;
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Create file asynchronously */
if ((file_id[i] = H5Fcreate_async(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_open);
if ((int)i > max_printf_file)
max_printf_file = (int)i;
/* Create the dataset asynchronously */
if ((dset_id[i] = H5Dcreate_async(file_id[i], "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_open);
/* Initialize write_buf. Must use a new slice of write_buf for
* each dset since we can't overwrite the buffers until I/O is done. */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id[i], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_open);
} /* end for */
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id[0], &is_native_vol) < 0)
PART_TEST_ERROR(multi_file_dset_open);
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. Skip this
* function because it isn't supported for the native vol in parallel. */
if (!is_native_vol && H5Oflush_async(dset_id[i], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_open);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
if (H5Dread_async(dset_id[i], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_open);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_dset_open);
if (op_failed)
PART_TEST_ERROR(multi_file_dset_open);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_file_dset_open);
} /* end if */
/* Close the datasets */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++)
if (H5Dclose(dset_id[i]) < 0)
PART_TEST_ERROR(multi_file_dset_open);
PASSED();
}
PART_END(multi_file_dset_open);
PART_BEGIN(multi_file_dset_dclose)
{
size_t buf_start_idx;
TESTING_2("closing datasets between I/O");
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
size_t buf_end_idx;
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id[i], "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
/* Initialize write_buf. */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank * 10;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
} /* end for */
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
/* Flush the file asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id[i], H5F_SCOPE_LOCAL, es_id) < 0)
PART_TEST_ERROR(multi_file_dset_open);
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id[i], "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
if (H5Dread_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
if (op_failed)
PART_TEST_ERROR(multi_file_dset_dclose);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_file_dset_dclose);
} /* end if */
/* Close the files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++)
if (H5Fclose(file_id[i]) < 0)
PART_TEST_ERROR(multi_file_dset_dclose);
PASSED();
}
PART_END(multi_file_dset_dclose);
PART_BEGIN(multi_file_dset_fclose)
{
size_t buf_start_idx;
TESTING_2("closing files between I/O");
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
size_t buf_end_idx;
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Open the file asynchronously */
if ((file_id[0] = H5Fopen_async(file_name, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id[0], "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Initialize write_buf. */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank + 5;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Close the file asynchronously */
if (H5Fclose_async(file_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
if (op_failed)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Loop over files */
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Open the file asynchronously */
if ((file_id[0] = H5Fopen_async(file_name, H5F_ACC_RDONLY, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Open the dataset asynchronously */
if ((dset_id[0] = H5Dopen_async(file_id[0], "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_FILE_DATASET_IO_TEST_NFILES / sizeof(int));
if (H5Dread_async(dset_id[0], H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Close the file asynchronously */
if (H5Fclose_async(file_id[0], es_id) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_dset_fclose);
if (op_failed)
PART_TEST_ERROR(multi_file_dset_fclose);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_file_dset_fclose);
} /* end if */
PASSED();
}
PART_END(multi_file_dset_fclose);
}
END_MULTIPART;
TESTING_2("test cleanup");
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Sclose(mspace_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Sclose(mspace_id);
for (i = 0; i < MULTI_FILE_DATASET_IO_TEST_NFILES; i++) {
H5Dclose(dset_id[i]);
H5Fclose(file_id[i]);
}
H5Pclose(fapl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef MULTI_FILE_DATASET_IO_TEST_SPACE_RANK
#undef MULTI_FILE_DATASET_IO_TEST_NFILES
/*
* Create multiple files, each with a single group and dataset. Each rank
* writes to a portion of each dataset and reads from a portion of each dataset.
*/
#define MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK 2
#define MULTI_FILE_GRP_DSET_IO_TEST_NFILES 5
static int
test_multi_file_grp_dset_io(void)
{
hsize_t *dims = NULL;
hsize_t start[MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK];
hsize_t stride[MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK];
hsize_t count[MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK];
hsize_t block[MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK];
hbool_t op_failed;
size_t i, j, data_size, num_in_progress;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t grp_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
char file_name[32];
int *write_buf = NULL;
int *read_buf = NULL;
TESTING_MULTIPART("multi file dataset I/O with groups")
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(
" API functions for basic file, group, or dataset aren't supported with this connector\n");
}
return 0;
}
TESTING_2("test setup");
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Calculate size of data buffers - first dimension is skipped in calculation */
for (i = 1, data_size = 1; i < MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
data_size *= MULTI_FILE_GRP_DSET_IO_TEST_NFILES;
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset read\n");
TEST_ERROR;
}
/* Select this rank's portion of the dataspace */
for (i = 0; i < MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK; i++) {
if (i == 0) {
start[i] = (hsize_t)mpi_rank;
block[i] = 1;
}
else {
start[i] = 0;
block[i] = dims[i];
}
stride[i] = 1;
count[i] = 1;
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Setup memory space for write_buf */
{
hsize_t mdims[] = {data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int)};
if ((mspace_id = H5Screate_simple(1, mdims, NULL)) < 0) {
H5_FAILED();
HDprintf(" couldn't create memory dataspace\n");
goto error;
}
}
PASSED();
BEGIN_MULTIPART
{
PART_BEGIN(multi_file_grp_dset_no_kick)
{
size_t buf_start_idx;
TESTING_2("without intermediate calls to H5ESwait()");
/* Loop over files */
for (i = 0; i < MULTI_FILE_GRP_DSET_IO_TEST_NFILES; i++) {
size_t buf_end_idx;
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Create file asynchronously */
if ((file_id = H5Fcreate_async(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
if ((int)i > max_printf_file)
max_printf_file = (int)i;
/* Create the group asynchronously */
if ((grp_id = H5Gcreate_async(file_id, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(grp_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Initialize write_buf. Must use a new slice of write_buf for
* each dset since we can't overwrite the buffers until I/O is done. */
buf_start_idx = i * (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the group asynchronously */
if (H5Gclose_async(grp_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the file asynchronously */
if (H5Fclose_async(file_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Loop over files */
for (i = 0; i < MULTI_FILE_GRP_DSET_IO_TEST_NFILES; i++) {
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Open the file asynchronously */
if ((file_id = H5Fopen_async(file_name, H5F_ACC_RDONLY, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Open the group asynchronously */
if ((grp_id = H5Gopen_async(file_id, "grp", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Open the dataset asynchronously */
if ((dset_id = H5Dopen_async(grp_id, "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the group asynchronously */
if (H5Gclose_async(grp_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Close the file asynchronously */
if (H5Fclose_async(file_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_no_kick);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_file_grp_dset_no_kick);
} /* end if */
PASSED();
}
PART_END(multi_file_grp_dset_no_kick);
PART_BEGIN(multi_file_grp_dset_kick)
{
size_t buf_start_idx;
TESTING_2("with intermediate calls to H5ESwait() (0 timeout)");
/* Loop over files */
for (i = 0; i < MULTI_FILE_GRP_DSET_IO_TEST_NFILES; i++) {
size_t buf_end_idx;
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Create file asynchronously */
if ((file_id = H5Fcreate_async(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
if ((int)i > max_printf_file)
max_printf_file = (int)i;
/* Create the group asynchronously */
if ((grp_id = H5Gcreate_async(file_id, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(grp_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Initialize write_buf. Must use a new slice of write_buf for
* each dset since we can't overwrite the buffers until I/O is done. */
buf_start_idx = i * (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
buf_end_idx = buf_start_idx + (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
for (j = buf_start_idx; j < buf_end_idx; j++)
((int *)write_buf)[j] = mpi_rank;
/* Write the dataset asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&write_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the group asynchronously */
if (H5Gclose_async(grp_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the file asynchronously */
if (H5Fclose_async(file_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Kick the event stack to make progress */
if (H5ESwait(es_id, 0, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_kick);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Loop over files */
for (i = 0; i < MULTI_FILE_GRP_DSET_IO_TEST_NFILES; i++) {
/* Set file name */
sprintf(file_name, PAR_ASYNC_API_TEST_FILE_PRINTF, (int)i);
/* Open the file asynchronously */
if ((file_id = H5Fopen_async(file_name, H5F_ACC_RDONLY, fapl_id, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Open the group asynchronously */
if ((grp_id = H5Gopen_async(file_id, "grp", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Open the dataset asynchronously */
if ((dset_id = H5Dopen_async(grp_id, "dset", H5P_DEFAULT, es_id)) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Read the dataset asynchronously */
buf_start_idx = i * (data_size / MULTI_FILE_GRP_DSET_IO_TEST_NFILES / sizeof(int));
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT,
&read_buf[buf_start_idx], es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the group asynchronously */
if (H5Gclose_async(grp_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Close the file asynchronously */
if (H5Fclose_async(file_id, es_id) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Kick the event stack to make progress */
if (H5ESwait(es_id, 0, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_kick);
} /* end for */
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
PART_TEST_ERROR(multi_file_grp_dset_kick);
if (op_failed)
PART_TEST_ERROR(multi_file_grp_dset_kick);
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
PART_ERROR(multi_file_grp_dset_kick);
} /* end if */
PASSED();
}
PART_END(multi_file_grp_dset_kick);
}
END_MULTIPART;
TESTING_2("test cleanup");
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Sclose(mspace_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Sclose(mspace_id);
H5Dclose(dset_id);
H5Gclose(grp_id);
H5Fclose(file_id);
H5Pclose(fapl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef MULTI_FILE_GRP_DSET_IO_TEST_SPACE_RANK
#undef MULTI_FILE_GRP_DSET_IO_TEST_NFILES
/*
* Creates a single file and dataset, then each rank writes to a portion
* of the dataset. Next, the dataset is continually extended in the first
* dimension by 1 "row" per mpi rank and partially written to by each rank.
* Finally, each rank reads from a portion of the dataset.
*/
#define SET_EXTENT_TEST_SPACE_RANK 2
#define SET_EXTENT_TEST_NUM_EXTENDS 6
static int
test_set_extent(void)
{
hsize_t *dims = NULL;
hsize_t *maxdims = NULL;
hsize_t *cdims = NULL;
hsize_t start[SET_EXTENT_TEST_SPACE_RANK];
hsize_t stride[SET_EXTENT_TEST_SPACE_RANK];
hsize_t count[SET_EXTENT_TEST_SPACE_RANK];
hsize_t block[SET_EXTENT_TEST_SPACE_RANK];
hbool_t op_failed = false;
hbool_t is_native_vol = false;
size_t i, j, data_size, num_in_progress;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t dcpl_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t space_id_out = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
htri_t tri_ret;
int *write_buf = NULL;
int *read_buf = NULL;
TESTING("extending dataset");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, dataset, dataset more, or flush aren't supported "
"with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(SET_EXTENT_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
if (NULL == (maxdims = HDmalloc(SET_EXTENT_TEST_SPACE_RANK * sizeof(hsize_t)))) {
H5_FAILED();
HDprintf(" couldn't allocate max dataspace dimension buffer\n");
TEST_ERROR;
}
if (NULL == (cdims = HDmalloc(SET_EXTENT_TEST_SPACE_RANK * sizeof(hsize_t)))) {
H5_FAILED();
HDprintf(" couldn't allocate chunk dimension buffer\n");
TEST_ERROR;
}
for (i = 0; i < SET_EXTENT_TEST_SPACE_RANK; i++) {
maxdims[i] = (i == 0) ? dims[i] + (hsize_t)(SET_EXTENT_TEST_NUM_EXTENDS * mpi_size) : dims[i];
cdims[i] = (dims[i] == 1) ? 1 : dims[i] / 2;
}
/* Create file dataspace */
if ((space_id = H5Screate_simple(SET_EXTENT_TEST_SPACE_RANK, dims, maxdims)) < 0)
TEST_ERROR;
/* Create DCPL */
if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
TEST_ERROR;
/* Set chunking */
if (H5Pset_chunk(dcpl_id, SET_EXTENT_TEST_SPACE_RANK, cdims) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Create file asynchronously */
if ((file_id = H5Fcreate_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(file_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, dcpl_id,
H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers - first dimension is skipped in calculation */
for (i = 1, data_size = 1; i < SET_EXTENT_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
data_size *= SET_EXTENT_TEST_NUM_EXTENDS;
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for dataset read\n");
TEST_ERROR;
}
/* Select this rank's portion of the dataspace */
for (i = 0; i < SET_EXTENT_TEST_SPACE_RANK; i++) {
if (i == 0) {
start[i] = (hsize_t)mpi_rank;
block[i] = 1;
}
else {
start[i] = 0;
block[i] = dims[i];
}
stride[i] = 1;
count[i] = 1;
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Setup memory space for write_buf */
{
hsize_t mdims[] = {data_size / SET_EXTENT_TEST_NUM_EXTENDS / sizeof(int)};
if ((mspace_id = H5Screate_simple(1, mdims, NULL)) < 0) {
H5_FAILED();
HDprintf(" couldn't create memory dataspace\n");
goto error;
}
}
/* Initialize write_buf */
for (i = 0; i < data_size / sizeof(int); i++)
((int *)write_buf)[i] = mpi_rank;
/* Extend the dataset in the first dimension n times, extending by 1 "row" per
* mpi rank involved on each iteration. Each rank will claim one of the new
* "rows" for I/O in an interleaved fashion. */
for (i = 0; i < SET_EXTENT_TEST_NUM_EXTENDS; i++) {
/* No need to extend on the first iteration */
if (i) {
/* Extend datapace */
dims[0] += (hsize_t)mpi_size;
if (H5Sset_extent_simple(space_id, SET_EXTENT_TEST_SPACE_RANK, dims, maxdims) < 0)
TEST_ERROR;
/* Extend dataset asynchronously */
if (H5Dset_extent_async(dset_id, dims, es_id) < 0)
TEST_ERROR;
/* Select hyperslab in file space to match new region */
for (j = 0; j < SET_EXTENT_TEST_SPACE_RANK; j++) {
if (j == 0) {
start[j] = (hsize_t)mpi_rank;
block[j] = 1;
stride[j] = (hsize_t)mpi_size;
count[j] = i + 1;
}
else {
start[j] = 0;
block[j] = dims[j];
stride[j] = 1;
count[j] = 1;
}
}
if (H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) < 0) {
H5_FAILED();
HDprintf(" couldn't select hyperslab for dataset write\n");
goto error;
}
/* Adjust memory dataspace to match as well */
{
hsize_t mdims[] = {(i + 1) * (data_size / SET_EXTENT_TEST_NUM_EXTENDS / sizeof(int))};
if (H5Sset_extent_simple(mspace_id, 1, mdims, NULL) < 0)
TEST_ERROR;
if (H5Sselect_all(mspace_id) < 0)
TEST_ERROR;
}
} /* end if */
/* Get dataset dataspace */
if ((space_id_out = H5Dget_space_async(dset_id, es_id)) < 0)
TEST_ERROR;
/* Verify extent is correct */
if ((tri_ret = H5Sextent_equal(space_id, space_id_out)) < 0)
TEST_ERROR;
if (!tri_ret)
FAIL_PUTS_ERROR(" dataspaces are not equal\n");
/* Close output dataspace */
if (H5Sclose(space_id_out) < 0)
TEST_ERROR;
/* Write the dataset slice asynchronously */
if (H5Dwrite_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, write_buf, es_id) < 0)
TEST_ERROR;
}
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. Skip this
* function because it isn't supported for the native vol in parallel. */
if (!is_native_vol && H5Oflush_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Read the entire dataset asynchronously */
if (H5Dread_async(dset_id, H5T_NATIVE_INT, mspace_id, space_id, H5P_DEFAULT, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed, expected %d but got %d\n", write_buf[i], read_buf[i]);
goto error;
} /* end if */
/* Close dataset asynchronously */
if (H5Dclose_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Open dataset asynchronously */
if ((dset_id = H5Dopen_async(file_id, "dset", H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Get dataset dataspace asynchronously */
if ((space_id_out = H5Dget_space_async(dset_id, es_id)) < 0)
TEST_ERROR;
/* Verify the extents match */
if ((tri_ret = H5Sextent_equal(space_id, space_id_out)) < 0)
TEST_ERROR;
if (!tri_ret)
FAIL_PUTS_ERROR(" dataspaces are not equal\n");
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (cdims) {
HDfree(cdims);
cdims = NULL;
}
if (maxdims) {
HDfree(maxdims);
maxdims = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (H5Dclose(dset_id) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Sclose(mspace_id) < 0)
TEST_ERROR;
if (H5Pclose(dcpl_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (cdims)
HDfree(cdims);
if (maxdims)
HDfree(maxdims);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Sclose(mspace_id);
H5Sclose(space_id_out);
H5Dclose(dset_id);
H5Pclose(dcpl_id);
H5Fclose(file_id);
H5Pclose(fapl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef SET_EXTENT_TEST_SPACE_RANK
#undef SET_EXTENT_TEST_NUM_EXTENDS
/*
* Creates an attribute on a dataset. All ranks check to see
* if the attribute exists before and after creating the
* attribute on the dataset.
*/
#define ATTRIBUTE_EXISTS_TEST_SPACE_RANK 2
static int
test_attribute_exists(void)
{
hsize_t *dims = NULL;
hbool_t op_failed = false;
hbool_t is_native_vol = false;
size_t num_in_progress;
hbool_t exists1 = false;
hbool_t exists2 = false;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
TESTING("H5Aexists()");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, dataset, dataset more, attribute, or flush aren't "
"supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(ATTRIBUTE_EXISTS_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(ATTRIBUTE_EXISTS_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(file_id, "attr_exists_dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Check if the attribute exists asynchronously */
if (H5Aexists_async(dset_id, "attr", &exists1, es_id) < 0)
TEST_ERROR;
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the create takes place after the existence check.
* Skip this function because it isn't supported for the native vol in parallel.
*/
if (!is_native_vol && H5Oflush_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Create the attribute asynchronously */
if ((attr_id =
H5Acreate_async(dset_id, "attr", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the existence check takes place after the create.
* Skip this function because it isn't supported for the native vol in parallel.
*/
if (!is_native_vol && H5Oflush_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Check if the attribute exists asynchronously */
if (H5Aexists_async(dset_id, "attr", &exists2, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Check if H5Aexists returned the correct values */
if (exists1)
FAIL_PUTS_ERROR(" H5Aexists returned TRUE for an attribute that should not exist")
if (!exists2)
FAIL_PUTS_ERROR(" H5Aexists returned FALSE for an attribute that should exist")
/* Close */
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
if (H5Dclose_async(dset_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Aclose(attr_id);
H5Dclose(dset_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef ATTRIBUTE_EXISTS_TEST_SPACE_RANK
/*
* Creates a file, dataset and attribute. Each rank writes to
* the attribute. Then, each rank reads the attribute and
* verifies the data is correct.
*/
#define ATTRIBUTE_IO_TEST_SPACE_RANK 2
static int
test_attribute_io(void)
{
hsize_t *dims = NULL;
hbool_t op_failed = false;
hbool_t is_native_vol = false;
size_t num_in_progress;
size_t i, data_size;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
int *write_buf = NULL;
int *read_buf = NULL;
TESTING("attribute I/O");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, dataset, dataset more, attribute, or flush aren't "
"supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(ATTRIBUTE_IO_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(ATTRIBUTE_IO_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the dataset asynchronously */
if ((dset_id = H5Dcreate_async(file_id, "attr_dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Create the attribute asynchronously */
if ((attr_id =
H5Acreate_async(dset_id, "attr", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers */
for (i = 0, data_size = 1; i < ATTRIBUTE_IO_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute read\n");
TEST_ERROR;
}
/* Initialize write_buf. */
for (i = 0; i < data_size / sizeof(int); i++)
write_buf[i] = 10 * (int)i;
/* Write the attribute asynchronously */
if (H5Awrite_async(attr_id, H5T_NATIVE_INT, write_buf, es_id) < 0)
TEST_ERROR;
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write.
* Skip this function because it isn't supported for the native vol in parallel.
*/
if (!is_native_vol && H5Oflush_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, H5T_NATIVE_INT, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
goto error;
} /* end if */
/* Close the attribute asynchronously */
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
/* Open the attribute asynchronously */
if ((attr_id = H5Aopen_async(dset_id, "attr", H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, H5T_NATIVE_INT, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
goto error;
} /* end if */
/* Close out of order to see if it trips things up */
if (H5Dclose_async(dset_id, es_id) < 0)
TEST_ERROR;
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Aclose(attr_id);
H5Dclose(dset_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Creates a file, dataset and attribute in parallel. Each rank writes to
* the attribute with datatype conversion involved, then reads back the
* attribute and verifies the data is correct.
*/
#define ATTRIBUTE_IO_TCONV_TEST_SPACE_RANK 2
static int
test_attribute_io_tconv(void)
{
hsize_t *dims = NULL;
hbool_t op_failed;
size_t num_in_progress;
size_t i, data_size;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
int *write_buf = NULL;
int *read_buf = NULL;
TESTING("attribute I/O with type conversion");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, attribute, or flush aren't supported with this "
"connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(ATTRIBUTE_IO_TCONV_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(ATTRIBUTE_IO_TCONV_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Create the attribute asynchronously by name */
if ((attr_id = H5Acreate_by_name_async(file_id, "attr_dset", "attr_tconv", H5T_STD_U16BE, space_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers */
for (i = 0, data_size = 1; i < ATTRIBUTE_IO_TCONV_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(int);
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute read\n");
TEST_ERROR;
}
/* Initialize write_buf. */
for (i = 0; i < data_size / sizeof(int); i++)
write_buf[i] = 10 * (int)i;
/* Write the attribute asynchronously */
if (H5Awrite_async(attr_id, H5T_NATIVE_INT, write_buf, es_id) < 0)
TEST_ERROR;
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
TEST_ERROR;
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, H5T_NATIVE_INT, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
goto error;
} /* end if */
/* Close the attribute asynchronously */
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
/* Open the attribute asynchronously */
if ((attr_id =
H5Aopen_by_name_async(file_id, "attr_dset", "attr_tconv", H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, H5T_NATIVE_INT, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(int); i++)
if (write_buf[i] != read_buf[i]) {
H5_FAILED();
HDprintf(" data verification failed\n");
goto error;
} /* end if */
/* Close */
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Aclose(attr_id);
H5Dclose(dset_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Creates a file, dataset and attribute in parallel. Each rank writes to
* the attribute with a compound datatype, then reads back the attribute
* and verifies the data is correct.
*/
typedef struct tattr_cmpd_t {
int a;
int b;
} tattr_cmpd_t;
#define ATTRIBUTE_IO_COMPOUND_TEST_SPACE_RANK 2
static int
test_attribute_io_compound(void)
{
hsize_t *dims = NULL;
hbool_t op_failed;
size_t num_in_progress;
size_t i, data_size;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t mtype_id = H5I_INVALID_HID;
hid_t ftype_id = H5I_INVALID_HID;
hid_t mtypea_id = H5I_INVALID_HID;
hid_t mtypeb_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
tattr_cmpd_t *write_buf = NULL;
tattr_cmpd_t *read_buf = NULL;
tattr_cmpd_t *fbuf = NULL;
TESTING("attribute I/O with compound type conversion");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, dataset, dataset more, attribute, or flush aren't "
"supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(ATTRIBUTE_IO_COMPOUND_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create datatype */
if ((mtype_id = H5Tcreate(H5T_COMPOUND, sizeof(tattr_cmpd_t))) < 0)
TEST_ERROR;
if (H5Tinsert(mtype_id, "a_name", HOFFSET(tattr_cmpd_t, a), H5T_NATIVE_INT) < 0)
TEST_ERROR;
if (H5Tinsert(mtype_id, "b_name", HOFFSET(tattr_cmpd_t, b), H5T_NATIVE_INT) < 0)
TEST_ERROR;
if ((mtypea_id = H5Tcreate(H5T_COMPOUND, sizeof(tattr_cmpd_t))) < 0)
TEST_ERROR;
if (H5Tinsert(mtypea_id, "a_name", HOFFSET(tattr_cmpd_t, a), H5T_NATIVE_INT) < 0)
TEST_ERROR;
if ((mtypeb_id = H5Tcreate(H5T_COMPOUND, sizeof(tattr_cmpd_t))) < 0)
TEST_ERROR;
if (H5Tinsert(mtypeb_id, "b_name", HOFFSET(tattr_cmpd_t, b), H5T_NATIVE_INT) < 0)
TEST_ERROR;
if ((ftype_id = H5Tcreate(H5T_COMPOUND, 2 + 8)) < 0)
TEST_ERROR;
if (H5Tinsert(ftype_id, "a_name", 0, H5T_STD_U16BE) < 0)
TEST_ERROR;
if (H5Tinsert(ftype_id, "b_name", 2, H5T_STD_I64LE) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(ATTRIBUTE_IO_COMPOUND_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Create the attribute asynchronously by name */
if ((attr_id = H5Acreate_by_name_async(file_id, "attr_dset", "attr_cmpd", ftype_id, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Calculate size of data buffers */
for (i = 0, data_size = 1; i < ATTRIBUTE_IO_COMPOUND_TEST_SPACE_RANK; i++)
data_size *= dims[i];
data_size *= sizeof(tattr_cmpd_t);
if (NULL == (write_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute write\n");
TEST_ERROR;
}
if (NULL == (read_buf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute read\n");
TEST_ERROR;
}
if (NULL == (fbuf = HDmalloc(data_size))) {
H5_FAILED();
HDprintf(" couldn't allocate buffer for attribute read verification\n");
TEST_ERROR;
}
/* Initialize write_buf. */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
write_buf[i].a = 10 * (int)i;
write_buf[i].b = (10 * (int)i) + 1;
}
/* Write the attribute asynchronously */
if (H5Awrite_async(attr_id, mtype_id, write_buf, es_id) < 0)
TEST_ERROR;
/* Update fbuf */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
fbuf[i].a = write_buf[i].a;
fbuf[i].b = write_buf[i].b;
}
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
TEST_ERROR;
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, mtype_id, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
if (read_buf[i].a != fbuf[i].a) {
H5_FAILED();
HDprintf(" data verification failed for field 'a'\n");
goto error;
} /* end if */
if (read_buf[i].b != fbuf[i].b) {
H5_FAILED();
HDprintf(" data verification failed for field 'b'\n");
goto error;
} /* end if */
}
/* Clear the read buffer */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
read_buf[i].a = -2;
read_buf[i].b = -2;
}
/* Read the attribute asynchronously (element a only) */
if (H5Aread_async(attr_id, mtypea_id, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
if (read_buf[i].a != fbuf[i].a) {
H5_FAILED();
HDprintf(" data verification failed for field 'a'\n");
goto error;
} /* end if */
if (read_buf[i].b != -2) {
H5_FAILED();
HDprintf(" data verification failed for field 'b'\n");
goto error;
} /* end if */
}
/* Clear the read buffer */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
read_buf[i].a = -2;
read_buf[i].b = -2;
}
/* Read the attribute asynchronously (element b only) */
if (H5Aread_async(attr_id, mtypeb_id, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
if (read_buf[i].a != -2) {
H5_FAILED();
HDprintf(" data verification failed for field 'a'\n");
goto error;
} /* end if */
if (read_buf[i].b != fbuf[i].b) {
H5_FAILED();
HDprintf(" data verification failed for field 'b'\n");
goto error;
} /* end if */
}
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
/* Update write_buf */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
write_buf[i].a += 2 * 6 * 10;
write_buf[i].b += 2 * 6 * 10;
}
/* Write the attribute asynchronously (element a only) */
if (H5Awrite_async(attr_id, mtypea_id, write_buf, es_id) < 0)
TEST_ERROR;
/* Update fbuf */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
fbuf[i].a = write_buf[i].a;
}
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
TEST_ERROR;
/* Clear the read buffer */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
read_buf[i].a = -2;
read_buf[i].b = -2;
}
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, mtype_id, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
if (read_buf[i].a != fbuf[i].a) {
H5_FAILED();
HDprintf(" data verification failed for field 'a'\n");
goto error;
} /* end if */
if (read_buf[i].b != fbuf[i].b) {
H5_FAILED();
HDprintf(" data verification failed for field 'b'\n");
goto error;
} /* end if */
}
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
/* Update write_buf */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
write_buf[i].a += 2 * 6 * 10;
write_buf[i].b += 2 * 6 * 10;
}
/* Write the attribute asynchronously (element b only) */
if (H5Awrite_async(attr_id, mtypeb_id, write_buf, es_id) < 0)
TEST_ERROR;
/* Update fbuf */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
fbuf[i].b = write_buf[i].b;
}
/* Flush the dataset asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
TEST_ERROR;
/* Clear the read buffer */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
read_buf[i].a = -2;
read_buf[i].b = -2;
}
/* Read the attribute asynchronously */
if (H5Aread_async(attr_id, mtype_id, read_buf, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify the read data */
for (i = 0; i < data_size / sizeof(tattr_cmpd_t); i++) {
if (read_buf[i].a != fbuf[i].a) {
H5_FAILED();
HDprintf(" data verification failed for field 'a'\n");
goto error;
} /* end if */
if (read_buf[i].b != fbuf[i].b) {
H5_FAILED();
HDprintf(" data verification failed for field 'b'\n");
goto error;
} /* end if */
}
/* Close */
if (H5Aclose_async(attr_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Tclose(mtype_id) < 0)
TEST_ERROR;
if (H5Tclose(ftype_id) < 0)
TEST_ERROR;
if (H5Tclose(mtypea_id) < 0)
TEST_ERROR;
if (H5Tclose(mtypeb_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
if (write_buf) {
HDfree(write_buf);
write_buf = NULL;
}
if (fbuf) {
HDfree(fbuf);
fbuf = NULL;
}
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (read_buf)
HDfree(read_buf);
if (write_buf)
HDfree(write_buf);
if (fbuf)
HDfree(fbuf);
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Tclose(mtype_id);
H5Tclose(ftype_id);
H5Tclose(mtypea_id);
H5Tclose(mtypeb_id);
H5Aclose(attr_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Tests async group interfaces in parallel
*/
static int
test_group(void)
{
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t parent_group_id = H5I_INVALID_HID;
hid_t group_id = H5I_INVALID_HID;
hid_t subgroup_id = H5I_INVALID_HID;
hid_t gcpl_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
H5G_info_t info1;
H5G_info_t info2;
H5G_info_t info3;
size_t num_in_progress;
hbool_t op_failed;
TESTING("group operations");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, group, group more, creation order, or flush aren't "
"supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create GCPL */
if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0)
TEST_ERROR;
/* Track creation order */
if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Create the parent group asynchronously */
if ((parent_group_id =
H5Gcreate_async(file_id, "group_parent", H5P_DEFAULT, gcpl_id, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Create 3 subgroups asynchronously, the first with no sub-subgroups, the
* second with 1, and the third with 2 */
if ((group_id =
H5Gcreate_async(parent_group_id, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
if (H5Gclose_async(group_id, es_id) < 0)
TEST_ERROR;
if ((group_id =
H5Gcreate_async(parent_group_id, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
if ((subgroup_id = H5Gcreate_async(group_id, "subgroup1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
TEST_ERROR;
if (H5Gclose_async(subgroup_id, es_id) < 0)
TEST_ERROR;
if (H5Gclose_async(group_id, es_id) < 0)
TEST_ERROR;
if ((group_id =
H5Gcreate_async(parent_group_id, "group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
if ((subgroup_id = H5Gcreate_async(group_id, "subgroup1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
TEST_ERROR;
if (H5Gclose_async(subgroup_id, es_id) < 0)
TEST_ERROR;
if ((subgroup_id = H5Gcreate_async(group_id, "subgroup2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
TEST_ERROR;
if (H5Gclose_async(subgroup_id, es_id) < 0)
TEST_ERROR;
if (H5Gclose_async(group_id, es_id) < 0)
TEST_ERROR;
/* Flush the file asynchronously. This will effectively work as a barrier,
* guaranteeing the read takes place after the write. */
if (H5Fflush_async(file_id, H5F_SCOPE_LOCAL, es_id) < 0)
TEST_ERROR;
/* Test H5Gget_info_async */
/* Open group1 asynchronously */
if ((group_id = H5Gopen_async(parent_group_id, "group1", H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Get info */
if (H5Gget_info_async(group_id, &info1, es_id) < 0)
TEST_ERROR;
/* Test H5Gget_info_by_idx_async */
if (H5Gget_info_by_idx_async(parent_group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &info2,
H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Test H5Gget_info_by_name_async */
if (H5Gget_info_by_name_async(parent_group_id, "group3", &info3, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Verify group infos */
if (info1.nlinks != 0)
FAIL_PUTS_ERROR(" incorrect number of links")
if (info2.nlinks != 1)
FAIL_PUTS_ERROR(" incorrect number of links")
if (info3.nlinks != 2)
FAIL_PUTS_ERROR(" incorrect number of links")
/* Close */
if (H5Gclose_async(group_id, es_id) < 0)
TEST_ERROR;
if (H5Gclose_async(parent_group_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Pclose(gcpl_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Gclose(subgroup_id);
H5Gclose(group_id);
H5Gclose(parent_group_id);
H5Fclose(file_id);
H5Pclose(fapl_id);
H5Pclose(gcpl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Tests async link interfaces in parallel
*/
static int
test_link(void)
{
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t parent_group_id = H5I_INVALID_HID;
hid_t group_id = H5I_INVALID_HID;
hid_t gcpl_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
hbool_t existsh1;
hbool_t existsh2;
hbool_t existsh3;
hbool_t existss1;
hbool_t existss2;
hbool_t existss3;
size_t num_in_progress;
hbool_t op_failed = false;
hbool_t is_native_vol = false;
TESTING("link operations");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, link, hard link, soft link, flush, or creation order "
"aren't supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create GCPL */
if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0)
TEST_ERROR;
/* Track creation order */
if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the parent group asynchronously */
if ((parent_group_id =
H5Gcreate_async(file_id, "link_parent", H5P_DEFAULT, gcpl_id, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Create subgroup asynchronously. */
if ((group_id = H5Gcreate_async(parent_group_id, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) <
0)
TEST_ERROR;
if (H5Gclose_async(group_id, es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the link to the subgroup is visible to later tasks.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Create hard link asynchronously */
if (H5Lcreate_hard_async(parent_group_id, "group", parent_group_id, "hard_link", H5P_DEFAULT, H5P_DEFAULT,
es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the soft link create takes place after the hard
* link create. Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Create soft link asynchronously */
if (H5Lcreate_soft_async("/link_parent/group", parent_group_id, "soft_link", H5P_DEFAULT, H5P_DEFAULT,
es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the writes.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
/* Check if hard link exists */
if (H5Lexists_async(parent_group_id, "hard_link", &existsh1, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Check if soft link exists */
if (H5Lexists_async(parent_group_id, "soft_link", &existss1, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the delete takes place after the reads.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Delete soft link by index */
if (H5Ldelete_by_idx_async(parent_group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, H5P_DEFAULT, es_id) <
0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the delete.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
/* Check if hard link exists */
if (H5Lexists_async(parent_group_id, "hard_link", &existsh2, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Check if soft link exists */
if (H5Lexists_async(parent_group_id, "soft_link", &existss2, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the delete takes place after the reads.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Delete hard link */
if (H5Ldelete_async(parent_group_id, "hard_link", H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the read takes place after the delete.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
/* Check if hard link exists */
if (H5Lexists_async(parent_group_id, "hard_link", &existsh3, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Check if soft link exists */
if (H5Lexists_async(parent_group_id, "soft_link", &existss3, H5P_DEFAULT, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Check if existence returns were correct */
if (!existsh1)
FAIL_PUTS_ERROR(" link exists returned FALSE for link that should exist")
if (!existss1)
FAIL_PUTS_ERROR(" link exists returned FALSE for link that should exist")
if (!existsh2)
FAIL_PUTS_ERROR(" link exists returned FALSE for link that should exist")
if (existss2)
FAIL_PUTS_ERROR(" link exists returned TRUE for link that should not exist")
if (existsh3)
FAIL_PUTS_ERROR(" link exists returned TRUE for link that should not exist")
if (existsh3)
FAIL_PUTS_ERROR(" link exists returned TRUE for link that should not exist")
/* Close */
if (H5Gclose_async(parent_group_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Pclose(gcpl_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Gclose(group_id);
H5Gclose(parent_group_id);
H5Fclose(file_id);
H5Pclose(fapl_id);
H5Pclose(gcpl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Tests H5Ocopy_async and H5Orefresh_async in parallel
*/
#define OCOPY_REFRESH_TEST_SPACE_RANK 2
static int
test_ocopy_orefresh(void)
{
hsize_t *dims = NULL;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t parent_group_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
size_t num_in_progress;
hbool_t op_failed = false;
hbool_t is_native_vol = false;
TESTING("H5Ocopy() and H5Orefresh()");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file, group, dataset, object more, flush, or refresh "
"aren't supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create dataspace */
if (generate_random_parallel_dimensions(OCOPY_REFRESH_TEST_SPACE_RANK, &dims) < 0)
TEST_ERROR;
/* Create dataspace */
if ((space_id = H5Screate_simple(OCOPY_REFRESH_TEST_SPACE_RANK, dims, NULL)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Find out if the native connector is used */
if (H5VLobject_is_native(file_id, &is_native_vol) < 0)
TEST_ERROR;
/* Create the parent group asynchronously */
if ((parent_group_id =
H5Gcreate_async(file_id, "ocopy_parent", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Create dataset asynchronously. */
if ((dset_id = H5Dcreate_async(parent_group_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
if (H5Dclose_async(dset_id, es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the copy takes place after dataset create.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
/* Copy dataset */
if (H5Ocopy_async(parent_group_id, "dset", parent_group_id, "copied_dset", H5P_DEFAULT, H5P_DEFAULT,
es_id) < 0)
TEST_ERROR;
/* Flush the parent group asynchronously. This will effectively work as a
* barrier, guaranteeing the dataset open takes place copy.
* Skip this function for the native vol because it isn't supported in parallel.
*/
if (!is_native_vol && H5Oflush_async(parent_group_id, es_id) < 0)
TEST_ERROR;
if (!coll_metadata_read) {
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier failed\n");
goto error;
}
}
/* Open the copied dataset asynchronously */
if ((dset_id = H5Dopen_async(parent_group_id, "copied_dset", H5P_DEFAULT, es_id)) < 0)
TEST_ERROR;
/* Refresh the copied dataset asynchronously */
if (H5Orefresh(dset_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Close */
if (H5Dclose_async(dset_id, es_id) < 0)
TEST_ERROR;
if (H5Gclose_async(parent_group_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (dims) {
HDfree(dims);
dims = NULL;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (dims)
HDfree(dims);
H5Sclose(space_id);
H5Dclose(dset_id);
H5Gclose(parent_group_id);
H5Pclose(fapl_id);
H5Fclose(file_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
#undef OCOPY_REFRESH_TEST_SPACE_RANK
/*
* Tests H5Freopen_async in parallel
*/
static int
test_file_reopen(void)
{
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t reopened_file_id = H5I_INVALID_HID;
hid_t es_id = H5I_INVALID_HID;
size_t num_in_progress;
hbool_t op_failed;
TESTING("H5Freopen()");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_MORE)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" API functions for basic file or file more aren't supported with this connector\n");
}
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, coll_metadata_read)) < 0)
TEST_ERROR;
/* Create event stack */
if ((es_id = H5EScreate()) < 0)
TEST_ERROR;
/* Open file asynchronously */
if ((file_id = H5Fopen_async(PAR_ASYNC_API_TEST_FILE, H5F_ACC_RDWR, fapl_id, es_id)) < 0)
TEST_ERROR;
/* Reopen file asynchronously */
if ((reopened_file_id = H5Freopen_async(file_id, es_id)) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
/* Close */
if (H5Fclose_async(reopened_file_id, es_id) < 0)
TEST_ERROR;
if (H5Fclose_async(file_id, es_id) < 0)
TEST_ERROR;
/* Wait for the event stack to complete */
if (H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed) < 0)
TEST_ERROR;
if (op_failed)
TEST_ERROR;
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5ESclose(es_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Fclose(reopened_file_id);
H5Fclose(file_id);
H5Pclose(fapl_id);
H5ESwait(es_id, H5_API_TEST_WAIT_FOREVER, &num_in_progress, &op_failed);
H5ESclose(es_id);
}
H5E_END_TRY;
return 1;
}
/*
* Cleanup temporary test files
*/
static void
cleanup_files(void)
{
char file_name[64];
int i;
if (MAINPROCESS) {
H5Fdelete(PAR_ASYNC_API_TEST_FILE, H5P_DEFAULT);
for (i = 0; i <= max_printf_file; i++) {
snprintf(file_name, 64, PAR_ASYNC_API_TEST_FILE_PRINTF, i);
H5Fdelete(file_name, H5P_DEFAULT);
} /* end for */
}
}
int
H5_api_async_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Async Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_ASYNC)) {
if (MAINPROCESS) {
SKIPPED();
HDprintf(" Async APIs aren't supported with this connector\n");
}
return 0;
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_async_tests); i++) {
nerrors += (*par_async_tests[i])() ? 1 : 0;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS) {
HDprintf("\n");
HDprintf("Cleaning up testing files\n");
}
cleanup_files();
if (MAINPROCESS) {
HDprintf("\n * Re-testing with independent metadata reads *\n");
}
coll_metadata_read = FALSE;
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_async_tests); i++) {
nerrors += (*par_async_tests[i])() ? 1 : 0;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS) {
HDprintf("\n");
HDprintf("Cleaning up testing files\n");
}
cleanup_files();
return nerrors;
}
#else /* H5ESpublic_H */
int
H5_api_async_test_parallel(void)
{
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Async Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
HDprintf("SKIPPED due to no async support in HDF5 library\n");
return 0;
}
#endif
+29
View File
@@ -0,0 +1,29 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_ASYNC_TEST_PARALLEL_H_
#define H5_API_ASYNC_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_async_test_parallel(void);
/********************************************************
* *
* API parallel async test defines *
* *
********************************************************/
#define PAR_ASYNC_API_TEST_FILE "H5_api_async_test_parallel.h5"
#define PAR_ASYNC_API_TEST_FILE_PRINTF "H5_api_async_test_parallel_%d.h5"
#endif /* H5_API_ASYNC_TEST_PARALLEL_H_ */
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_attribute_test_parallel.h"
/*
* The array of parallel attribute tests to be performed.
*/
static int (*par_attribute_tests[])(void) = {NULL};
int
H5_api_attribute_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Attribute Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_attribute_tests); i++) {
/* nerrors += (*par_attribute_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_ATTRIBUTE_TEST_PARALLEL_H_
#define H5_API_ATTRIBUTE_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_attribute_test_parallel(void);
#endif /* H5_API_ATTRIBUTE_TEST_PARALLEL_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_DATASET_TEST_PARALLEL_H_
#define H5_API_DATASET_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_dataset_test_parallel(void);
#endif /* H5_API_DATASET_TEST_PARALLEL_H_ */
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_datatype_test_parallel.h"
/*
* The array of parallel datatype tests to be performed.
*/
static int (*par_datatype_tests[])(void) = {NULL};
int
H5_api_datatype_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Datatype Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_datatype_tests); i++) {
/* nerrors += (*par_datatype_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_DATATYPE_TEST_PARALLEL_H_
#define H5_API_DATATYPE_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_datatype_test_parallel(void);
#endif /* H5_API_DATATYPE_TEST_PARALLEL_H_ */
+367
View File
@@ -0,0 +1,367 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_file_test_parallel.h"
static int test_create_file(void);
static int test_open_file(void);
static int test_split_comm_file_access(void);
/*
* The array of parallel file tests to be performed.
*/
static int (*par_file_tests[])(void) = {
test_create_file,
test_open_file,
test_split_comm_file_access,
};
/*
* A test to ensure that a file can be created in parallel.
*/
#define FILE_CREATE_TEST_FILENAME "test_file_parallel.h5"
static int
test_create_file(void)
{
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
TESTING("H5Fcreate");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
SKIPPED();
HDprintf(" API functions for basic file aren't supported with this connector\n");
return 0;
}
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, TRUE)) < 0)
TEST_ERROR;
if ((file_id = H5Fcreate(FILE_CREATE_TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) {
H5_FAILED();
HDprintf(" couldn't create file '%s'\n", FILE_CREATE_TEST_FILENAME);
goto error;
}
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Pclose(fapl_id);
H5Fclose(file_id);
}
H5E_END_TRY;
return 1;
}
/*
* A test to ensure that a file can be opened in parallel.
*/
static int
test_open_file(void)
{
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
TESTING_MULTIPART("H5Fopen");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
SKIPPED();
HDprintf(" API functions for basic file aren't supported with this connector\n");
return 0;
}
TESTING_2("test setup");
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, TRUE)) < 0)
TEST_ERROR;
PASSED();
BEGIN_MULTIPART
{
PART_BEGIN(H5Fopen_rdonly)
{
TESTING_2("H5Fopen in read-only mode");
if ((file_id = H5Fopen(H5_api_test_parallel_filename, H5F_ACC_RDONLY, fapl_id)) < 0) {
H5_FAILED();
HDprintf(" unable to open file '%s' in read-only mode\n", H5_api_test_parallel_filename);
PART_ERROR(H5Fopen_rdonly);
}
PASSED();
}
PART_END(H5Fopen_rdonly);
if (file_id >= 0) {
H5E_BEGIN_TRY
{
H5Fclose(file_id);
}
H5E_END_TRY;
file_id = H5I_INVALID_HID;
}
PART_BEGIN(H5Fopen_rdwrite)
{
TESTING_2("H5Fopen in read-write mode");
if ((file_id = H5Fopen(H5_api_test_parallel_filename, H5F_ACC_RDWR, fapl_id)) < 0) {
H5_FAILED();
HDprintf(" unable to open file '%s' in read-write mode\n", H5_api_test_parallel_filename);
PART_ERROR(H5Fopen_rdwrite);
}
PASSED();
}
PART_END(H5Fopen_rdwrite);
if (file_id >= 0) {
H5E_BEGIN_TRY
{
H5Fclose(file_id);
}
H5E_END_TRY;
file_id = H5I_INVALID_HID;
}
/*
* XXX: SWMR open flags
*/
}
END_MULTIPART;
TESTING_2("test cleanup");
if (H5Pclose(fapl_id) < 0)
TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Pclose(fapl_id);
H5Fclose(file_id);
}
H5E_END_TRY;
return 1;
}
/*
* Tests file access by a communicator other than MPI_COMM_WORLD.
*
* Splits MPI_COMM_WORLD into two groups, where one (even_comm) contains
* the original processes of even ranks. The other (odd_comm) contains
* the original processes of odd ranks. Processes in even_comm create a
* file, then close it, using even_comm. Processes in old_comm just do
* a barrier using odd_comm. Then they all do a barrier using MPI_COMM_WORLD.
* If the file creation and close does not do correct collective action
* according to the communicator argument, the processes will freeze up
* sooner or later due to MPI_Barrier calls being mixed up.
*/
#define SPLIT_FILE_COMM_TEST_FILE_NAME "split_comm_file.h5"
static int
test_split_comm_file_access(void)
{
MPI_Comm comm;
MPI_Info info = MPI_INFO_NULL;
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
int is_old;
int newrank;
int err_occurred = 0;
TESTING("file access with a split communicator");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
SKIPPED();
HDprintf(" API functions for basic file aren't supported with this connector\n");
return 0;
}
/* set up MPI parameters */
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
is_old = mpi_rank % 2;
if (MPI_SUCCESS != MPI_Comm_split(MPI_COMM_WORLD, is_old, mpi_rank, &comm)) {
H5_FAILED();
HDprintf(" failed to split communicator!\n");
goto error;
}
MPI_Comm_rank(comm, &newrank);
if (is_old) {
/* odd-rank processes */
if (MPI_SUCCESS != MPI_Barrier(comm)) {
err_occurred = 1;
goto access_end;
}
}
else {
/* even-rank processes */
int sub_mpi_rank; /* rank in the sub-comm */
MPI_Comm_rank(comm, &sub_mpi_rank);
/* setup file access template */
if ((fapl_id = create_mpi_fapl(comm, info, TRUE)) < 0) {
err_occurred = 1;
goto access_end;
}
/* create the file collectively */
if ((file_id = H5Fcreate(SPLIT_FILE_COMM_TEST_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) {
H5_FAILED();
HDprintf(" couldn't create file '%s'\n", SPLIT_FILE_COMM_TEST_FILE_NAME);
err_occurred = 1;
goto access_end;
}
/* close the file */
if (H5Fclose(file_id) < 0) {
H5_FAILED();
HDprintf(" failed to close file '%s'\n", SPLIT_FILE_COMM_TEST_FILE_NAME);
err_occurred = 1;
goto access_end;
}
/* delete the test file */
if (H5Fdelete(SPLIT_FILE_COMM_TEST_FILE_NAME, fapl_id) < 0) {
H5_FAILED();
HDprintf(" failed to delete file '%s'\n", SPLIT_FILE_COMM_TEST_FILE_NAME);
err_occurred = 1;
goto access_end;
}
/* Release file-access template */
if (H5Pclose(fapl_id) < 0) {
err_occurred = 1;
goto access_end;
}
}
access_end:
/* Get the collective results about whether an error occurred */
if (MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &err_occurred, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Allreduce failed\n");
goto error;
}
if (err_occurred) {
H5_FAILED();
HDprintf(" an error occurred on only some ranks during split-communicator file access! - "
"collectively failing\n");
goto error;
}
if (MPI_SUCCESS != MPI_Comm_free(&comm)) {
H5_FAILED();
HDprintf(" MPI_Comm_free failed\n");
goto error;
}
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
H5_FAILED();
HDprintf(" MPI_Barrier on MPI_COMM_WORLD failed\n");
goto error;
}
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
H5Pclose(fapl_id);
H5Fclose(file_id);
}
H5E_END_TRY;
return 1;
}
/*
* Cleanup temporary test files
*/
static void
cleanup_files(void)
{
hid_t fapl_id = H5I_INVALID_HID;
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, TRUE)) < 0) {
if (MAINPROCESS)
HDprintf(" failed to create FAPL for deleting test files\n");
return;
}
H5Fdelete(FILE_CREATE_TEST_FILENAME, fapl_id);
/* The below file is deleted as part of the test */
/* H5Fdelete(SPLIT_FILE_COMM_TEST_FILE_NAME, H5P_DEFAULT); */
if (H5Pclose(fapl_id) < 0) {
if (MAINPROCESS)
HDprintf(" failed to close FAPL used for deleting test files\n");
return;
}
}
int
H5_api_file_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel File Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_file_tests); i++) {
nerrors += (*par_file_tests[i])() ? 1 : 0;
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS) {
HDprintf("\n");
HDprintf("Cleaning up testing files\n");
}
cleanup_files();
return nerrors;
}
+20
View File
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_FILE_TEST_PARALLEL_H_
#define H5_API_FILE_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_file_test_parallel(void);
#endif /* H5_API_FILE_TEST_PARALLEL_H_ */
+47
View File
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_group_test_parallel.h"
/*
* The array of parallel group tests to be performed.
*/
static int (*par_group_tests[])(void) = {NULL};
int
H5_api_group_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Group Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_group_tests); i++) {
/* nerrors += (*par_group_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
+20
View File
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_GROUP_TEST_PARALLEL_H_
#define H5_API_GROUP_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_group_test_parallel(void);
#endif /* H5_API_GROUP_TEST_PARALLEL_H_ */
+47
View File
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_link_test_parallel.h"
/*
* The array of parallel link tests to be performed.
*/
static int (*par_link_tests[])(void) = {NULL};
int
H5_api_link_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Link Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_link_tests); i++) {
/* nerrors += (*par_link_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
+20
View File
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_LINK_TEST_PARALLEL_H_
#define H5_API_LINK_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_link_test_parallel(void);
#endif /* H5_API_LINK_TEST_PARALLEL_H_ */
+47
View File
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_misc_test_parallel.h"
/*
* The array of parallel miscellaneous tests to be performed.
*/
static int (*par_misc_tests[])(void) = {NULL};
int
H5_api_misc_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Miscellaneous Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_misc_tests); i++) {
/* nerrors += (*par_misc_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
+20
View File
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_MISC_TEST_PARALLEL_H_
#define H5_API_MISC_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_misc_test_parallel(void);
#endif /* H5_API_MISC_TEST_PARALLEL_H_ */
+47
View File
@@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_object_test_parallel.h"
/*
* The array of parallel object tests to be performed.
*/
static int (*par_object_tests[])(void) = {NULL};
int
H5_api_object_test_parallel(void)
{
size_t i;
int nerrors;
if (MAINPROCESS) {
HDprintf("**********************************************\n");
HDprintf("* *\n");
HDprintf("* API Parallel Object Tests *\n");
HDprintf("* *\n");
HDprintf("**********************************************\n\n");
}
for (i = 0, nerrors = 0; i < ARRAY_LENGTH(par_object_tests); i++) {
/* nerrors += (*par_object_tests[i])() ? 1 : 0; */
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" MPI_Barrier() failed!\n");
}
}
if (MAINPROCESS)
HDprintf("\n");
return nerrors;
}
+20
View File
@@ -0,0 +1,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_OBJECT_TEST_PARALLEL_H_
#define H5_API_OBJECT_TEST_PARALLEL_H_
#include "H5_api_test_parallel.h"
int H5_api_object_test_parallel(void);
#endif /* H5_API_OBJECT_TEST_PARALLEL_H_ */
+338
View File
@@ -0,0 +1,338 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 "H5_api_test_util.h"
#include "H5_api_test_parallel.h"
#include "H5_api_attribute_test_parallel.h"
#include "H5_api_dataset_test_parallel.h"
#include "H5_api_datatype_test_parallel.h"
#include "H5_api_file_test_parallel.h"
#include "H5_api_group_test_parallel.h"
#include "H5_api_link_test_parallel.h"
#include "H5_api_misc_test_parallel.h"
#include "H5_api_object_test_parallel.h"
#ifdef H5_API_TEST_HAVE_ASYNC
#include "H5_api_async_test_parallel.h"
#endif
char H5_api_test_parallel_filename[H5_API_TEST_FILENAME_MAX_LENGTH];
const char *test_path_prefix;
size_t n_tests_run_g;
size_t n_tests_passed_g;
size_t n_tests_failed_g;
size_t n_tests_skipped_g;
int mpi_size;
int mpi_rank;
/* X-macro to define the following for each test:
* - enum type
* - name
* - test function
* - enabled by default
*/
#ifdef H5_API_TEST_HAVE_ASYNC
#define H5_API_PARALLEL_TESTS \
X(H5_API_TEST_NULL, "", NULL, 0) \
X(H5_API_TEST_FILE, "file", H5_api_file_test_parallel, 1) \
X(H5_API_TEST_GROUP, "group", H5_api_group_test_parallel, 1) \
X(H5_API_TEST_DATASET, "dataset", H5_api_dataset_test_parallel, 1) \
X(H5_API_TEST_DATATYPE, "datatype", H5_api_datatype_test_parallel, 1) \
X(H5_API_TEST_ATTRIBUTE, "attribute", H5_api_attribute_test_parallel, 1) \
X(H5_API_TEST_LINK, "link", H5_api_link_test_parallel, 1) \
X(H5_API_TEST_OBJECT, "object", H5_api_object_test_parallel, 1) \
X(H5_API_TEST_MISC, "misc", H5_api_misc_test_parallel, 1) \
X(H5_API_TEST_ASYNC, "async", H5_api_async_test_parallel, 1) \
X(H5_API_TEST_MAX, "", NULL, 0)
#else
#define H5_API_PARALLEL_TESTS \
X(H5_API_TEST_NULL, "", NULL, 0) \
X(H5_API_TEST_FILE, "file", H5_api_file_test_parallel, 1) \
X(H5_API_TEST_GROUP, "group", H5_api_group_test_parallel, 1) \
X(H5_API_TEST_DATASET, "dataset", H5_api_dataset_test_parallel, 1) \
X(H5_API_TEST_DATATYPE, "datatype", H5_api_datatype_test_parallel, 1) \
X(H5_API_TEST_ATTRIBUTE, "attribute", H5_api_attribute_test_parallel, 1) \
X(H5_API_TEST_LINK, "link", H5_api_link_test_parallel, 1) \
X(H5_API_TEST_OBJECT, "object", H5_api_object_test_parallel, 1) \
X(H5_API_TEST_MISC, "misc", H5_api_misc_test_parallel, 1) \
X(H5_API_TEST_MAX, "", NULL, 0)
#endif
#define X(a, b, c, d) a,
enum H5_api_test_type { H5_API_PARALLEL_TESTS };
#undef X
#define X(a, b, c, d) b,
static const char *const H5_api_test_name[] = {H5_API_PARALLEL_TESTS};
#undef X
#define X(a, b, c, d) c,
static int (*H5_api_test_func[])(void) = {H5_API_PARALLEL_TESTS};
#undef X
#define X(a, b, c, d) d,
static int H5_api_test_enabled[] = {H5_API_PARALLEL_TESTS};
#undef X
static enum H5_api_test_type
H5_api_test_name_to_type(const char *test_name)
{
enum H5_api_test_type i = 0;
while (strcmp(H5_api_test_name[i], test_name) && i != H5_API_TEST_MAX)
i++;
return ((i == H5_API_TEST_MAX) ? H5_API_TEST_NULL : i);
}
static void
H5_api_test_run(void)
{
enum H5_api_test_type i;
for (i = H5_API_TEST_FILE; i < H5_API_TEST_MAX; i++)
if (H5_api_test_enabled[i])
(void)H5_api_test_func[i]();
}
hid_t
create_mpi_fapl(MPI_Comm comm, MPI_Info info, hbool_t coll_md_read)
{
hid_t ret_pl = H5I_INVALID_HID;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if ((ret_pl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
goto error;
if (H5Pset_fapl_mpio(ret_pl, comm, info) < 0)
goto error;
if (H5Pset_all_coll_metadata_ops(ret_pl, coll_md_read) < 0)
goto error;
if (H5Pset_coll_metadata_write(ret_pl, TRUE) < 0)
goto error;
return ret_pl;
error:
return H5I_INVALID_HID;
} /* end create_mpi_fapl() */
/*
* Generates random dimensions for a dataspace. The first dimension
* is always `mpi_size` to allow for convenient subsetting; the rest
* of the dimensions are randomized.
*/
int
generate_random_parallel_dimensions(int space_rank, hsize_t **dims_out)
{
hsize_t *dims = NULL;
size_t i;
if (space_rank <= 0)
goto error;
if (NULL == (dims = HDmalloc((size_t)space_rank * sizeof(hsize_t))))
goto error;
if (MAINPROCESS) {
for (i = 0; i < (size_t)space_rank; i++) {
if (i == 0)
dims[i] = (hsize_t)mpi_size;
else
dims[i] = (hsize_t)((rand() % MAX_DIM_SIZE) + 1);
}
}
/*
* Ensure that the dataset dimensions are uniform across ranks.
*/
if (MPI_SUCCESS != MPI_Bcast(dims, space_rank, MPI_UNSIGNED_LONG_LONG, 0, MPI_COMM_WORLD))
goto error;
*dims_out = dims;
return 0;
error:
if (dims)
HDfree(dims);
return -1;
}
int
main(int argc, char **argv)
{
const char *vol_connector_name;
unsigned seed;
hid_t fapl_id = H5I_INVALID_HID;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Simple argument checking, TODO can improve that later */
if (argc > 1) {
enum H5_api_test_type i = H5_api_test_name_to_type(argv[1]);
if (i != H5_API_TEST_NULL) {
/* Run only specific API test */
memset(H5_api_test_enabled, 0, sizeof(H5_api_test_enabled));
H5_api_test_enabled[i] = 1;
}
}
/*
* Make sure that HDF5 is initialized on all MPI ranks before proceeding.
* This is important for certain VOL connectors which may require a
* collective initialization.
*/
H5open();
n_tests_run_g = 0;
n_tests_passed_g = 0;
n_tests_failed_g = 0;
n_tests_skipped_g = 0;
if (MAINPROCESS) {
seed = (unsigned)HDtime(NULL);
}
if (mpi_size > 1) {
if (MPI_SUCCESS != MPI_Bcast(&seed, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf("Couldn't broadcast test seed\n");
goto error;
}
}
srand(seed);
if (NULL == (test_path_prefix = HDgetenv(HDF5_API_TEST_PATH_PREFIX)))
test_path_prefix = "";
HDsnprintf(H5_api_test_parallel_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
PARALLEL_TEST_FILE_NAME);
if (NULL == (vol_connector_name = HDgetenv(HDF5_VOL_CONNECTOR))) {
if (MAINPROCESS)
HDprintf("No VOL connector selected; using native VOL connector\n");
vol_connector_name = "native";
}
if (MAINPROCESS) {
HDprintf("Running parallel API tests with VOL connector '%s'\n\n", vol_connector_name);
HDprintf("Test parameters:\n");
HDprintf(" - Test file name: '%s'\n", H5_api_test_parallel_filename);
HDprintf(" - Number of MPI ranks: %d\n", mpi_size);
HDprintf(" - Test seed: %u\n", seed);
HDprintf("\n\n");
}
/* Retrieve the VOL cap flags - work around an HDF5
* library issue by creating a FAPL
*/
BEGIN_INDEPENDENT_OP(get_capability_flags)
{
if ((fapl_id = create_mpi_fapl(MPI_COMM_WORLD, MPI_INFO_NULL, FALSE)) < 0) {
if (MAINPROCESS)
HDfprintf(stderr, "Unable to create FAPL\n");
INDEPENDENT_OP_ERROR(get_capability_flags);
}
vol_cap_flags_g = H5VL_CAP_FLAG_NONE;
if (H5Pget_vol_cap_flags(fapl_id, &vol_cap_flags_g) < 0) {
if (MAINPROCESS)
HDfprintf(stderr, "Unable to retrieve VOL connector capability flags\n");
INDEPENDENT_OP_ERROR(get_capability_flags);
}
}
END_INDEPENDENT_OP(get_capability_flags);
/*
* Create the file that will be used for all of the tests,
* except for those which test file creation.
*/
BEGIN_INDEPENDENT_OP(create_test_container)
{
if (MAINPROCESS) {
if (create_test_container(H5_api_test_parallel_filename, vol_cap_flags_g) < 0) {
HDprintf(" failed to create testing container file '%s'\n", H5_api_test_parallel_filename);
INDEPENDENT_OP_ERROR(create_test_container);
}
}
}
END_INDEPENDENT_OP(create_test_container);
/* Run all the tests that are enabled */
H5_api_test_run();
if (MAINPROCESS)
HDprintf("Cleaning up testing files\n");
H5Fdelete(H5_api_test_parallel_filename, fapl_id);
if (n_tests_run_g > 0) {
if (MAINPROCESS)
HDprintf("The below statistics are minimum values due to the possibility of some ranks failing a "
"test while others pass:\n");
if (MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &n_tests_passed_g, 1, MPI_UNSIGNED_LONG_LONG, MPI_MIN,
MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" failed to collect consensus about the minimum number of tests that passed -- "
"reporting rank 0's (possibly inaccurate) value\n");
}
if (MAINPROCESS)
HDprintf("%s%zu/%zu (%.2f%%) API tests passed across all ranks with VOL connector '%s'\n",
n_tests_passed_g > 0 ? "At least " : "", n_tests_passed_g, n_tests_run_g,
((double)n_tests_passed_g / (double)n_tests_run_g * 100.0), vol_connector_name);
if (MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &n_tests_failed_g, 1, MPI_UNSIGNED_LONG_LONG, MPI_MIN,
MPI_COMM_WORLD)) {
if (MAINPROCESS)
HDprintf(" failed to collect consensus about the minimum number of tests that failed -- "
"reporting rank 0's (possibly inaccurate) value\n");
}
if (MAINPROCESS) {
HDprintf("%s%zu/%zu (%.2f%%) API tests did not pass across all ranks with VOL connector '%s'\n",
n_tests_failed_g > 0 ? "At least " : "", n_tests_failed_g, n_tests_run_g,
((double)n_tests_failed_g / (double)n_tests_run_g * 100.0), vol_connector_name);
HDprintf("%zu/%zu (%.2f%%) API tests were skipped with VOL connector '%s'\n", n_tests_skipped_g,
n_tests_run_g, ((double)n_tests_skipped_g / (double)n_tests_run_g * 100.0),
vol_connector_name);
}
}
if (fapl_id >= 0 && H5Pclose(fapl_id) < 0) {
if (MAINPROCESS)
HDprintf(" failed to close MPI FAPL\n");
}
H5close();
MPI_Finalize();
HDexit(EXIT_SUCCESS);
error:
H5E_BEGIN_TRY
{
H5Pclose(fapl_id);
}
H5E_END_TRY;
MPI_Finalize();
HDexit(EXIT_FAILURE);
}
+188
View File
@@ -0,0 +1,188 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef H5_API_TEST_PARALLEL_H
#define H5_API_TEST_PARALLEL_H
#include <mpi.h>
#include "testpar.h"
#include "H5_api_test.h"
/* Define H5VL_VERSION if not already defined */
#ifndef H5VL_VERSION
#define H5VL_VERSION 0
#endif
/* Define macro to wait forever depending on version */
#if H5VL_VERSION >= 2
#define H5_API_TEST_WAIT_FOREVER H5ES_WAIT_FOREVER
#else
#define H5_API_TEST_WAIT_FOREVER UINT64_MAX
#endif
#define PARALLEL_TEST_FILE_NAME "H5_api_test_parallel.h5"
extern char H5_api_test_parallel_filename[];
#undef TESTING
#undef TESTING_2
#undef PASSED
#undef H5_FAILED
#undef H5_WARNING
#undef SKIPPED
#undef PUTS_ERROR
#undef TEST_ERROR
#undef STACK_ERROR
#undef FAIL_STACK_ERROR
#undef FAIL_PUTS_ERROR
#undef TESTING_MULTIPART
#define TESTING(WHAT) \
{ \
if (MAINPROCESS) { \
printf("Testing %-62s", WHAT); \
fflush(stdout); \
} \
n_tests_run_g++; \
}
#define TESTING_2(WHAT) \
{ \
if (MAINPROCESS) { \
printf(" Testing %-60s", WHAT); \
fflush(stdout); \
} \
n_tests_run_g++; \
}
#define PASSED() \
{ \
if (MAINPROCESS) { \
puts(" PASSED"); \
fflush(stdout); \
} \
n_tests_passed_g++; \
}
#define H5_FAILED() \
{ \
if (MAINPROCESS) { \
puts("*FAILED*"); \
fflush(stdout); \
} \
n_tests_failed_g++; \
}
#define H5_WARNING() \
{ \
if (MAINPROCESS) { \
puts("*WARNING*"); \
fflush(stdout); \
} \
}
#define SKIPPED() \
{ \
if (MAINPROCESS) { \
puts(" -SKIP-"); \
fflush(stdout); \
} \
n_tests_skipped_g++; \
}
#define PUTS_ERROR(s) \
{ \
if (MAINPROCESS) { \
puts(s); \
AT(); \
} \
goto error; \
}
#define TEST_ERROR \
{ \
H5_FAILED(); \
if (MAINPROCESS) { \
AT(); \
} \
goto error; \
}
#define STACK_ERROR \
{ \
if (MAINPROCESS) { \
H5Eprint2(H5E_DEFAULT, stdout); \
} \
goto error; \
}
#define FAIL_STACK_ERROR \
{ \
H5_FAILED(); \
if (MAINPROCESS) { \
AT(); \
H5Eprint2(H5E_DEFAULT, stdout); \
} \
goto error; \
}
#define FAIL_PUTS_ERROR(s) \
{ \
H5_FAILED(); \
if (MAINPROCESS) { \
AT(); \
puts(s); \
} \
goto error; \
}
#define TESTING_MULTIPART(WHAT) \
{ \
if (MAINPROCESS) { \
printf("Testing %-62s", WHAT); \
HDputs(""); \
fflush(stdout); \
} \
}
/*
* Macros to surround an action that will be performed non-collectively. Once the
* operation has completed, a consensus will be formed by all ranks on whether the
* operation failed.
*/
#define BEGIN_INDEPENDENT_OP(op_name) \
{ \
hbool_t ind_op_failed = FALSE; \
\
{
#define END_INDEPENDENT_OP(op_name) \
} \
\
op_##op_name##_end : if (MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &ind_op_failed, 1, MPI_C_BOOL, \
MPI_LOR, MPI_COMM_WORLD)) \
{ \
if (MAINPROCESS) \
HDprintf( \
" failed to collect consensus about whether non-collective operation was successful\n"); \
goto error; \
} \
\
if (ind_op_failed) { \
if (MAINPROCESS) \
HDprintf(" failure detected during non-collective operation - all other ranks will now fail " \
"too\n"); \
goto error; \
} \
}
#define INDEPENDENT_OP_ERROR(op_name) \
ind_op_failed = TRUE; \
goto op_##op_name##_end;
hid_t create_mpi_fapl(MPI_Comm comm, MPI_Info info, hbool_t coll_md_read);
int generate_random_parallel_dimensions(int space_rank, hsize_t **dims_out);
extern int mpi_size;
extern int mpi_rank;
#endif
+1942
View File
@@ -0,0 +1,1942 @@
#include "hdf5.h"
#include "testphdf5.h"
#if 0
#include "H5Dprivate.h" /* For Chunk tests */
#endif
/* FILENAME and filenames must have the same number of names */
const char *FILENAME[3] = {"bigio_test.h5", "single_rank_independent_io.h5", NULL};
/* Constants definitions */
#define MAX_ERR_REPORT 10 /* Maximum number of errors reported */
/* Define some handy debugging shorthands, routines, ... */
/* debugging tools */
#define MAIN_PROCESS (mpi_rank_g == 0) /* define process 0 as main process */
/* Constants definitions */
#define RANK 2
#define IN_ORDER 1
#define OUT_OF_ORDER 2
#define DATASET1 "DSET1"
#define DATASET2 "DSET2"
#define DATASET3 "DSET3"
#define DATASET4 "DSET4"
#define DXFER_COLLECTIVE_IO 0x1 /* Collective IO*/
#define DXFER_INDEPENDENT_IO 0x2 /* Independent IO collectively */
#define DXFER_BIGCOUNT (1 << 29)
#define HYPER 1
#define POINT 2
#define ALL 3
/* Dataset data type. Int's can be easily octo dumped. */
typedef hsize_t B_DATATYPE;
int facc_type = FACC_MPIO; /*Test file access type */
int dxfer_coll_type = DXFER_COLLECTIVE_IO;
size_t bigcount = (size_t) /* DXFER_BIGCOUNT */ 1310720;
int nerrors = 0;
static int mpi_size_g, mpi_rank_g;
hsize_t space_dim1 = SPACE_DIM1 * 256; // 4096
hsize_t space_dim2 = SPACE_DIM2;
static void coll_chunktest(const char *filename, int chunk_factor, int select_factor, int api_option,
int file_selection, int mem_selection, int mode);
/*
* Setup the coordinates for point selection.
*/
static void
set_coords(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], size_t num_points,
hsize_t coords[], int order)
{
hsize_t i, j, k = 0, m, n, s1, s2;
if (OUT_OF_ORDER == order)
k = (num_points * RANK) - 1;
else if (IN_ORDER == order)
k = 0;
s1 = start[0];
s2 = start[1];
for (i = 0; i < count[0]; i++)
for (j = 0; j < count[1]; j++)
for (m = 0; m < block[0]; m++)
for (n = 0; n < block[1]; n++)
if (OUT_OF_ORDER == order) {
coords[k--] = s2 + (stride[1] * j) + n;
coords[k--] = s1 + (stride[0] * i) + m;
}
else if (IN_ORDER == order) {
coords[k++] = s1 + stride[0] * i + m;
coords[k++] = s2 + stride[1] * j + n;
}
}
/*
* Fill the dataset with trivial data for testing.
* Assume dimension rank is 2 and data is stored contiguous.
*/
static void
fill_datasets(hsize_t start[], hsize_t block[], B_DATATYPE *dataset)
{
B_DATATYPE *dataptr = dataset;
hsize_t i, j;
/* put some trivial data in the data_array */
for (i = 0; i < block[0]; i++) {
for (j = 0; j < block[1]; j++) {
*dataptr = (B_DATATYPE)((i + start[0]) * 100 + (j + start[1] + 1));
dataptr++;
}
}
}
/*
* Setup the coordinates for point selection.
*/
void
point_set(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], size_t num_points,
hsize_t coords[], int order)
{
hsize_t i, j, k = 0, m, n, s1, s2;
HDcompile_assert(RANK == 2);
if (OUT_OF_ORDER == order)
k = (num_points * RANK) - 1;
else if (IN_ORDER == order)
k = 0;
s1 = start[0];
s2 = start[1];
for (i = 0; i < count[0]; i++)
for (j = 0; j < count[1]; j++)
for (m = 0; m < block[0]; m++)
for (n = 0; n < block[1]; n++)
if (OUT_OF_ORDER == order) {
coords[k--] = s2 + (stride[1] * j) + n;
coords[k--] = s1 + (stride[0] * i) + m;
}
else if (IN_ORDER == order) {
coords[k++] = s1 + stride[0] * i + m;
coords[k++] = s2 + stride[1] * j + n;
}
if (VERBOSE_MED) {
HDprintf("start[]=(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"count[]=(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"stride[]=(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"block[]=(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"total datapoints=%" PRIuHSIZE "\n",
start[0], start[1], count[0], count[1], stride[0], stride[1], block[0], block[1],
block[0] * block[1] * count[0] * count[1]);
k = 0;
for (i = 0; i < num_points; i++) {
HDprintf("(%d, %d)\n", (int)coords[k], (int)coords[k + 1]);
k += 2;
}
}
}
/*
* Print the content of the dataset.
*/
static void
dataset_print(hsize_t start[], hsize_t block[], B_DATATYPE *dataset)
{
B_DATATYPE *dataptr = dataset;
hsize_t i, j;
/* print the column heading */
HDprintf("%-8s", "Cols:");
for (j = 0; j < block[1]; j++) {
HDprintf("%3" PRIuHSIZE " ", start[1] + j);
}
HDprintf("\n");
/* print the slab data */
for (i = 0; i < block[0]; i++) {
HDprintf("Row %2" PRIuHSIZE ": ", i + start[0]);
for (j = 0; j < block[1]; j++) {
HDprintf("%" PRIuHSIZE " ", *dataptr++);
}
HDprintf("\n");
}
}
/*
* Print the content of the dataset.
*/
static int
verify_data(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], B_DATATYPE *dataset,
B_DATATYPE *original)
{
hsize_t i, j;
int vrfyerrs;
/* print it if VERBOSE_MED */
if (VERBOSE_MED) {
HDprintf("verify_data dumping:::\n");
HDprintf("start(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"count(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"stride(%" PRIuHSIZE ", %" PRIuHSIZE "), "
"block(%" PRIuHSIZE ", %" PRIuHSIZE ")\n",
start[0], start[1], count[0], count[1], stride[0], stride[1], block[0], block[1]);
HDprintf("original values:\n");
dataset_print(start, block, original);
HDprintf("compared values:\n");
dataset_print(start, block, dataset);
}
vrfyerrs = 0;
for (i = 0; i < block[0]; i++) {
for (j = 0; j < block[1]; j++) {
if (*dataset != *original) {
if (vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED) {
HDprintf("Dataset Verify failed at [%" PRIuHSIZE "][%" PRIuHSIZE "]"
"(row %" PRIuHSIZE ", col %" PRIuHSIZE "): "
"expect %" PRIuHSIZE ", got %" PRIuHSIZE "\n",
i, j, i + start[0], j + start[1], *(original), *(dataset));
}
dataset++;
original++;
}
}
}
if (vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (vrfyerrs)
HDprintf("%d errors found in verify_data\n", vrfyerrs);
return (vrfyerrs);
}
/* Set up the selection */
static void
ccslab_set(int mpi_rank, int mpi_size, hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[],
int mode)
{
switch (mode) {
case BYROW_CONT:
/* Each process takes a slabs of rows. */
block[0] = 1;
block[1] = 1;
stride[0] = 1;
stride[1] = 1;
count[0] = space_dim1;
count[1] = space_dim2;
start[0] = (hsize_t)mpi_rank * count[0];
start[1] = 0;
break;
case BYROW_DISCONT:
/* Each process takes several disjoint blocks. */
block[0] = 1;
block[1] = 1;
stride[0] = 3;
stride[1] = 3;
count[0] = space_dim1 / (stride[0] * block[0]);
count[1] = (space_dim2) / (stride[1] * block[1]);
start[0] = space_dim1 * (hsize_t)mpi_rank;
start[1] = 0;
break;
case BYROW_SELECTNONE:
/* Each process takes a slabs of rows, there are
no selections for the last process. */
block[0] = 1;
block[1] = 1;
stride[0] = 1;
stride[1] = 1;
count[0] = ((mpi_rank >= MAX(1, (mpi_size - 2))) ? 0 : space_dim1);
count[1] = space_dim2;
start[0] = (hsize_t)mpi_rank * count[0];
start[1] = 0;
break;
case BYROW_SELECTUNBALANCE:
/* The first one-third of the number of processes only
select top half of the domain, The rest will select the bottom
half of the domain. */
block[0] = 1;
count[0] = 2;
stride[0] = (hsize_t)(space_dim1 * (hsize_t)mpi_size / 4 + 1);
block[1] = space_dim2;
count[1] = 1;
start[1] = 0;
stride[1] = 1;
if ((mpi_rank * 3) < (mpi_size * 2))
start[0] = (hsize_t)mpi_rank;
else
start[0] = 1 + space_dim1 * (hsize_t)mpi_size / 2 + (hsize_t)(mpi_rank - 2 * mpi_size / 3);
break;
case BYROW_SELECTINCHUNK:
/* Each process will only select one chunk */
block[0] = 1;
count[0] = 1;
start[0] = (hsize_t)mpi_rank * space_dim1;
stride[0] = 1;
block[1] = space_dim2;
count[1] = 1;
stride[1] = 1;
start[1] = 0;
break;
default:
/* Unknown mode. Set it to cover the whole dataset. */
block[0] = space_dim1 * (hsize_t)mpi_size;
block[1] = space_dim2;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = 0;
break;
}
if (VERBOSE_MED) {
HDprintf("start[]=(%lu,%lu), count[]=(%lu,%lu), stride[]=(%lu,%lu), block[]=(%lu,%lu), total "
"datapoints=%lu\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1],
(unsigned long)(block[0] * block[1] * count[0] * count[1]));
}
}
/*
* Fill the dataset with trivial data for testing.
* Assume dimension rank is 2.
*/
static void
ccdataset_fill(hsize_t start[], hsize_t stride[], hsize_t count[], hsize_t block[], DATATYPE *dataset,
int mem_selection)
{
DATATYPE *dataptr = dataset;
DATATYPE *tmptr;
hsize_t i, j, k1, k2, k = 0;
/* put some trivial data in the data_array */
tmptr = dataptr;
/* assign the disjoint block (two-dimensional)data array value
through the pointer */
for (k1 = 0; k1 < count[0]; k1++) {
for (i = 0; i < block[0]; i++) {
for (k2 = 0; k2 < count[1]; k2++) {
for (j = 0; j < block[1]; j++) {
if (ALL != mem_selection) {
dataptr = tmptr + ((start[0] + k1 * stride[0] + i) * space_dim2 + start[1] +
k2 * stride[1] + j);
}
else {
dataptr = tmptr + k;
k++;
}
*dataptr = (DATATYPE)(k1 + k2 + i + j);
}
}
}
}
}
/*
* Print the first block of the content of the dataset.
*/
static void
ccdataset_print(hsize_t start[], hsize_t block[], DATATYPE *dataset)
{
DATATYPE *dataptr = dataset;
hsize_t i, j;
/* print the column heading */
HDprintf("Print only the first block of the dataset\n");
HDprintf("%-8s", "Cols:");
for (j = 0; j < block[1]; j++) {
HDprintf("%3lu ", (unsigned long)(start[1] + j));
}
HDprintf("\n");
/* print the slab data */
for (i = 0; i < block[0]; i++) {
HDprintf("Row %2lu: ", (unsigned long)(i + start[0]));
for (j = 0; j < block[1]; j++) {
HDprintf("%03d ", *dataptr++);
}
HDprintf("\n");
}
}
/*
* Print the content of the dataset.
*/
static int
ccdataset_vrfy(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], DATATYPE *dataset,
DATATYPE *original, int mem_selection)
{
hsize_t i, j, k1, k2, k = 0;
int vrfyerrs;
DATATYPE *dataptr, *oriptr;
/* print it if VERBOSE_MED */
if (VERBOSE_MED) {
HDprintf("dataset_vrfy dumping:::\n");
HDprintf("start(%lu, %lu), count(%lu, %lu), stride(%lu, %lu), block(%lu, %lu)\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1]);
HDprintf("original values:\n");
ccdataset_print(start, block, original);
HDprintf("compared values:\n");
ccdataset_print(start, block, dataset);
}
vrfyerrs = 0;
for (k1 = 0; k1 < count[0]; k1++) {
for (i = 0; i < block[0]; i++) {
for (k2 = 0; k2 < count[1]; k2++) {
for (j = 0; j < block[1]; j++) {
if (ALL != mem_selection) {
dataptr = dataset + ((start[0] + k1 * stride[0] + i) * space_dim2 + start[1] +
k2 * stride[1] + j);
oriptr = original + ((start[0] + k1 * stride[0] + i) * space_dim2 + start[1] +
k2 * stride[1] + j);
}
else {
dataptr = dataset + k;
oriptr = original + k;
k++;
}
if (*dataptr != *oriptr) {
if (vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED) {
HDprintf("Dataset Verify failed at [%lu][%lu]: expect %d, got %d\n",
(unsigned long)i, (unsigned long)j, *(oriptr), *(dataptr));
}
}
}
}
}
}
if (vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (vrfyerrs)
HDprintf("%d errors found in ccdataset_vrfy\n", vrfyerrs);
return (vrfyerrs);
}
/*
* Example of using the parallel HDF5 library to create two datasets
* in one HDF5 file with collective parallel access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
* each process controls a hyperslab within.]
*/
static void
dataset_big_write(void)
{
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset;
hsize_t dims[RANK]; /* dataset dim sizes */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
hsize_t *coords = NULL;
herr_t ret; /* Generic return value */
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
size_t num_points;
B_DATATYPE *wdata;
/* allocate memory for data buffer */
wdata = (B_DATATYPE *)HDmalloc(bigcount * sizeof(B_DATATYPE));
VRFY_G((wdata != NULL), "wdata malloc succeeded");
/* setup file access template */
acc_tpl = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((acc_tpl >= 0), "H5P_FILE_ACCESS");
H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL);
/* create the file collectively */
fid = H5Fcreate(FILENAME[0], H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY_G((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY_G((ret >= 0), "");
/* Each process takes a slabs of rows. */
if (mpi_rank_g == 0)
HDprintf("\nTesting Dataset1 write by ROW\n");
/* Create a large dataset */
dims[0] = bigcount;
dims[1] = (hsize_t)mpi_size_g;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY_G((sid >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(fid, DATASET1, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dcreate2 succeeded");
H5Sclose(sid);
block[0] = dims[0] / (hsize_t)mpi_size_g;
block[1] = dims[1];
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank_g * block[0];
start[1] = 0;
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* fill the local slab with some trivial data */
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, wdata);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, wdata);
VRFY_G((ret >= 0), "H5Dwrite dataset1 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
/* Each process takes a slabs of cols. */
if (mpi_rank_g == 0)
HDprintf("\nTesting Dataset2 write by COL\n");
/* Create a large dataset */
dims[0] = bigcount;
dims[1] = (hsize_t)mpi_size_g;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY_G((sid >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(fid, DATASET2, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dcreate2 succeeded");
H5Sclose(sid);
block[0] = dims[0];
block[1] = dims[1] / (hsize_t)mpi_size_g;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = (hsize_t)mpi_rank_g * block[1];
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* fill the local slab with some trivial data */
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, wdata);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, wdata);
VRFY_G((ret >= 0), "H5Dwrite dataset1 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
/* ALL selection */
if (mpi_rank_g == 0)
HDprintf("\nTesting Dataset3 write select ALL proc 0, NONE others\n");
/* Create a large dataset */
dims[0] = bigcount;
dims[1] = 1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY_G((sid >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(fid, DATASET3, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dcreate2 succeeded");
H5Sclose(sid);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
if (mpi_rank_g == 0) {
ret = H5Sselect_all(file_dataspace);
VRFY_G((ret >= 0), "H5Sset_all succeeded");
}
else {
ret = H5Sselect_none(file_dataspace);
VRFY_G((ret >= 0), "H5Sset_none succeeded");
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, dims, NULL);
VRFY_G((mem_dataspace >= 0), "");
if (mpi_rank_g != 0) {
ret = H5Sselect_none(mem_dataspace);
VRFY_G((ret >= 0), "H5Sset_none succeeded");
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
/* fill the local slab with some trivial data */
fill_datasets(start, dims, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
}
ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, wdata);
VRFY_G((ret >= 0), "H5Dwrite dataset1 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
/* Point selection */
if (mpi_rank_g == 0)
HDprintf("\nTesting Dataset4 write point selection\n");
/* Create a large dataset */
dims[0] = bigcount;
dims[1] = (hsize_t)(mpi_size_g * 4);
sid = H5Screate_simple(RANK, dims, NULL);
VRFY_G((sid >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(fid, DATASET4, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dcreate2 succeeded");
H5Sclose(sid);
block[0] = dims[0] / 2;
block[1] = 2;
stride[0] = dims[0] / 2;
stride[1] = 2;
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = dims[1] / (hsize_t)mpi_size_g * (hsize_t)mpi_rank_g;
num_points = bigcount;
coords = (hsize_t *)HDmalloc(num_points * RANK * sizeof(hsize_t));
VRFY_G((coords != NULL), "coords malloc succeeded");
set_coords(start, count, stride, block, num_points, coords, IN_ORDER);
/* create a file dataspace */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((ret >= 0), "H5Sselect_elements succeeded");
if (coords)
free(coords);
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, wdata);
}
/* create a memory dataspace */
/* Warning: H5Screate_simple requires an array of hsize_t elements
* even if we only pass only a single value. Attempting anything else
* appears to cause problems with 32 bit compilers.
*/
mem_dataspace = H5Screate_simple(1, dims, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, wdata);
VRFY_G((ret >= 0), "H5Dwrite dataset1 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
HDfree(wdata);
H5Fclose(fid);
}
/*
* Example of using the parallel HDF5 library to read two datasets
* in one HDF5 file with collective parallel access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
* each process controls a hyperslab within.]
*/
static void
dataset_big_read(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset;
B_DATATYPE *rdata = NULL; /* data buffer */
B_DATATYPE *wdata = NULL; /* expected data buffer */
hsize_t dims[RANK]; /* dataset dim sizes */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
size_t num_points;
hsize_t *coords = NULL;
herr_t ret; /* Generic return value */
/* allocate memory for data buffer */
rdata = (B_DATATYPE *)HDmalloc(bigcount * sizeof(B_DATATYPE));
VRFY_G((rdata != NULL), "rdata malloc succeeded");
wdata = (B_DATATYPE *)HDmalloc(bigcount * sizeof(B_DATATYPE));
VRFY_G((wdata != NULL), "wdata malloc succeeded");
HDmemset(rdata, 0, bigcount * sizeof(B_DATATYPE));
/* setup file access template */
acc_tpl = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((acc_tpl >= 0), "H5P_FILE_ACCESS");
H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL);
/* open the file collectively */
fid = H5Fopen(FILENAME[0], H5F_ACC_RDONLY, acc_tpl);
VRFY_G((fid >= 0), "H5Fopen succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY_G((ret >= 0), "");
if (mpi_rank_g == 0)
HDprintf("\nRead Testing Dataset1 by COL\n");
dataset = H5Dopen2(fid, DATASET1, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dopen2 succeeded");
dims[0] = bigcount;
dims[1] = (hsize_t)mpi_size_g;
/* Each process takes a slabs of cols. */
block[0] = dims[0];
block[1] = dims[1] / (hsize_t)mpi_size_g;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = (hsize_t)mpi_rank_g * block[1];
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* fill dataset with test data */
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, rdata);
VRFY_G((ret >= 0), "H5Dread dataset1 succeeded");
/* verify the read data with original expected data */
ret = verify_data(start, count, stride, block, rdata, wdata);
if (ret) {
HDfprintf(stderr, "verify failed\n");
exit(1);
}
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
if (mpi_rank_g == 0)
HDprintf("\nRead Testing Dataset2 by ROW\n");
HDmemset(rdata, 0, bigcount * sizeof(B_DATATYPE));
dataset = H5Dopen2(fid, DATASET2, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dopen2 succeeded");
dims[0] = bigcount;
dims[1] = (hsize_t)mpi_size_g;
/* Each process takes a slabs of rows. */
block[0] = dims[0] / (hsize_t)mpi_size_g;
block[1] = dims[1];
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank_g * block[0];
start[1] = 0;
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* fill dataset with test data */
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, rdata);
VRFY_G((ret >= 0), "H5Dread dataset2 succeeded");
/* verify the read data with original expected data */
ret = verify_data(start, count, stride, block, rdata, wdata);
if (ret) {
HDfprintf(stderr, "verify failed\n");
exit(1);
}
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
if (mpi_rank_g == 0)
HDprintf("\nRead Testing Dataset3 read select ALL proc 0, NONE others\n");
HDmemset(rdata, 0, bigcount * sizeof(B_DATATYPE));
dataset = H5Dopen2(fid, DATASET3, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dopen2 succeeded");
dims[0] = bigcount;
dims[1] = 1;
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
if (mpi_rank_g == 0) {
ret = H5Sselect_all(file_dataspace);
VRFY_G((ret >= 0), "H5Sset_all succeeded");
}
else {
ret = H5Sselect_none(file_dataspace);
VRFY_G((ret >= 0), "H5Sset_none succeeded");
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, dims, NULL);
VRFY_G((mem_dataspace >= 0), "");
if (mpi_rank_g != 0) {
ret = H5Sselect_none(mem_dataspace);
VRFY_G((ret >= 0), "H5Sset_none succeeded");
}
/* fill dataset with test data */
fill_datasets(start, dims, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, rdata);
VRFY_G((ret >= 0), "H5Dread dataset3 succeeded");
if (mpi_rank_g == 0) {
/* verify the read data with original expected data */
ret = verify_data(start, count, stride, block, rdata, wdata);
if (ret) {
HDfprintf(stderr, "verify failed\n");
exit(1);
}
}
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
if (mpi_rank_g == 0)
HDprintf("\nRead Testing Dataset4 with Point selection\n");
dataset = H5Dopen2(fid, DATASET4, H5P_DEFAULT);
VRFY_G((dataset >= 0), "H5Dopen2 succeeded");
dims[0] = bigcount;
dims[1] = (hsize_t)(mpi_size_g * 4);
block[0] = dims[0] / 2;
block[1] = 2;
stride[0] = dims[0] / 2;
stride[1] = 2;
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = dims[1] / (hsize_t)mpi_size_g * (hsize_t)mpi_rank_g;
fill_datasets(start, block, wdata);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, wdata);
}
num_points = bigcount;
coords = (hsize_t *)HDmalloc(num_points * RANK * sizeof(hsize_t));
VRFY_G((coords != NULL), "coords malloc succeeded");
set_coords(start, count, stride, block, num_points, coords, IN_ORDER);
/* create a file dataspace */
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((ret >= 0), "H5Sselect_elements succeeded");
if (coords)
HDfree(coords);
/* create a memory dataspace */
/* Warning: H5Screate_simple requires an array of hsize_t elements
* even if we only pass only a single value. Attempting anything else
* appears to cause problems with 32 bit compilers.
*/
mem_dataspace = H5Screate_simple(1, dims, NULL);
VRFY_G((mem_dataspace >= 0), "");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace, xfer_plist, rdata);
VRFY_G((ret >= 0), "H5Dread dataset1 succeeded");
ret = verify_data(start, count, stride, block, rdata, wdata);
if (ret) {
HDfprintf(stderr, "verify failed\n");
exit(1);
}
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
HDfree(wdata);
HDfree(rdata);
wdata = NULL;
rdata = NULL;
/* We never wrote Dataset5 in the write section, so we can't
* expect to read it...
*/
file_dataspace = -1;
mem_dataspace = -1;
xfer_plist = -1;
dataset = -1;
/* release all temporary handles. */
if (file_dataspace != -1)
H5Sclose(file_dataspace);
if (mem_dataspace != -1)
H5Sclose(mem_dataspace);
if (xfer_plist != -1)
H5Pclose(xfer_plist);
if (dataset != -1) {
ret = H5Dclose(dataset);
VRFY_G((ret >= 0), "H5Dclose1 succeeded");
}
H5Fclose(fid);
/* release data buffers */
if (rdata)
HDfree(rdata);
if (wdata)
HDfree(wdata);
} /* dataset_large_readAll */
static void
single_rank_independent_io(void)
{
if (mpi_rank_g == 0)
HDprintf("single_rank_independent_io\n");
if (MAIN_PROCESS) {
hsize_t dims[1];
hid_t file_id = -1;
hid_t fapl_id = -1;
hid_t dset_id = -1;
hid_t fspace_id = -1;
herr_t ret;
int *data = NULL;
uint64_t i;
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((fapl_id >= 0), "H5P_FILE_ACCESS");
H5Pset_fapl_mpio(fapl_id, MPI_COMM_SELF, MPI_INFO_NULL);
file_id = H5Fcreate(FILENAME[1], H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY_G((file_id >= 0), "H5Dcreate2 succeeded");
/*
* Calculate the number of elements needed to exceed
* MPI's INT_MAX limitation
*/
dims[0] = (INT_MAX / sizeof(int)) + 10;
fspace_id = H5Screate_simple(1, dims, NULL);
VRFY_G((fspace_id >= 0), "H5Screate_simple fspace_id succeeded");
/*
* Create and write to a >2GB dataset from a single rank.
*/
dset_id = H5Dcreate2(file_id, "test_dset", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
VRFY_G((dset_id >= 0), "H5Dcreate2 succeeded");
data = malloc(dims[0] * sizeof(int));
/* Initialize data */
for (i = 0; i < dims[0]; i++)
data[i] = (int)(i % (uint64_t)DXFER_BIGCOUNT);
/* Write data */
ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, fspace_id, H5P_DEFAULT, data);
VRFY_G((ret >= 0), "H5Dwrite succeeded");
/* Wipe buffer */
HDmemset(data, 0, dims[0] * sizeof(int));
/* Read data back */
ret = H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, fspace_id, H5P_DEFAULT, data);
VRFY_G((ret >= 0), "H5Dread succeeded");
/* Verify data */
for (i = 0; i < dims[0]; i++)
if (data[i] != (int)(i % (uint64_t)DXFER_BIGCOUNT)) {
HDfprintf(stderr, "verify failed\n");
exit(1);
}
free(data);
H5Sclose(fspace_id);
H5Dclose(dset_id);
H5Fclose(file_id);
H5Fdelete(FILENAME[1], fapl_id);
H5Pclose(fapl_id);
}
MPI_Barrier(MPI_COMM_WORLD);
}
/*
* Create the appropriate File access property list
*/
hid_t
create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type)
{
hid_t ret_pl = -1;
herr_t ret; /* generic return value */
int mpi_rank; /* mpi variables */
/* need the rank for error checking macros */
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((ret_pl >= 0), "H5P_FILE_ACCESS");
if (l_facc_type == FACC_DEFAULT)
return (ret_pl);
if (l_facc_type == FACC_MPIO) {
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(ret_pl, comm, info);
VRFY_G((ret >= 0), "");
ret = H5Pset_all_coll_metadata_ops(ret_pl, TRUE);
VRFY_G((ret >= 0), "");
ret = H5Pset_coll_metadata_write(ret_pl, TRUE);
VRFY_G((ret >= 0), "");
return (ret_pl);
}
if (l_facc_type == (FACC_MPIO | FACC_SPLIT)) {
hid_t mpio_pl;
mpio_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((mpio_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(mpio_pl, comm, info);
VRFY_G((ret >= 0), "");
/* setup file access template */
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY_G((ret_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_split(ret_pl, ".meta", mpio_pl, ".raw", mpio_pl);
VRFY_G((ret >= 0), "H5Pset_fapl_split succeeded");
H5Pclose(mpio_pl);
return (ret_pl);
}
/* unknown file access types */
return (ret_pl);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk1
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with a single chunk
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: One big singular selection inside one chunk
* Two dimensions,
*
* dim1 = space_dim1(5760)*mpi_size
* dim2 = space_dim2(3)
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = space_dim1(5760)
* count1 = space_dim2(3)
* start0 = mpi_rank*space_dim1
* start1 = 0
* ------------------------------------------------------------------------
*/
void
coll_chunk1(void)
{
const char *filename = FILENAME[0];
if (mpi_rank_g == 0)
HDprintf("coll_chunk1\n");
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk2
*
* Purpose: Wrapper to test the collective chunk IO for regular DISJOINT
selection with a single chunk
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: many disjoint selections inside one chunk
* Two dimensions,
*
* dim1 = space_dim1*mpi_size(5760)
* dim2 = space_dim2(3)
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 3 for all dimensions
* count0 = space_dim1/stride0(5760/3)
* count1 = space_dim2/stride(3/3 = 1)
* start0 = mpi_rank*space_dim1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk2(void)
{
const char *filename = FILENAME[0];
if (mpi_rank_g == 0)
HDprintf("coll_chunk2\n");
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk3
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = space_dim1*mpi_size
* dim2 = space_dim2(3)
* chunk_dim1 = space_dim1
* chunk_dim2 = dim2/2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = space_dim1
* count1 = space_dim2(3)
* start0 = mpi_rank*space_dim1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk3(void)
{
const char *filename = FILENAME[0];
if (mpi_rank_g == 0)
HDprintf("coll_chunk3\n");
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, mpi_size_g, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
}
//-------------------------------------------------------------------------
// Borrowed/Modified (slightly) from t_coll_chunk.c
/*-------------------------------------------------------------------------
* Function: coll_chunktest
*
* Purpose: The real testing routine for regular selection of collective
chunking storage
testing both write and read,
If anything fails, it may be read or write. There is no
separation test between read and write.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
*-------------------------------------------------------------------------
*/
static void
coll_chunktest(const char *filename, int chunk_factor, int select_factor, int api_option, int file_selection,
int mem_selection, int mode)
{
hid_t file, dataset, file_dataspace, mem_dataspace;
hid_t acc_plist, xfer_plist, crp_plist;
hsize_t dims[RANK], chunk_dims[RANK];
int *data_array1 = NULL;
int *data_origin1 = NULL;
hsize_t start[RANK], count[RANK], stride[RANK], block[RANK];
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
unsigned prop_value;
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
herr_t status;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
size_t num_points; /* for point selection */
hsize_t *coords = NULL; /* for point selection */
/* Create the data space */
acc_plist = create_faccess_plist(comm, info, facc_type);
VRFY_G((acc_plist >= 0), "");
file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_plist);
VRFY_G((file >= 0), "H5Fcreate succeeded");
status = H5Pclose(acc_plist);
VRFY_G((status >= 0), "");
/* setup dimensionality object */
dims[0] = space_dim1 * (hsize_t)mpi_size_g;
dims[1] = space_dim2;
/* allocate memory for data buffer */
data_array1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY_G((data_array1 != NULL), "data_array1 malloc succeeded");
/* set up dimensions of the slab this process accesses */
ccslab_set(mpi_rank_g, mpi_size_g, start, count, stride, block, select_factor);
/* set up the coords array selection */
num_points = block[0] * block[1] * count[0] * count[1];
coords = (hsize_t *)HDmalloc(num_points * RANK * sizeof(hsize_t));
VRFY_G((coords != NULL), "coords malloc succeeded");
point_set(start, count, stride, block, num_points, coords, mode);
/* Warning: H5Screate_simple requires an array of hsize_t elements
* even if we only pass only a single value. Attempting anything else
* appears to cause problems with 32 bit compilers.
*/
file_dataspace = H5Screate_simple(2, dims, NULL);
VRFY_G((file_dataspace >= 0), "file dataspace created succeeded");
if (ALL != mem_selection) {
mem_dataspace = H5Screate_simple(2, dims, NULL);
VRFY_G((mem_dataspace >= 0), "mem dataspace created succeeded");
}
else {
/* Putting the warning about H5Screate_simple (above) into practice... */
hsize_t dsdims[1] = {num_points};
mem_dataspace = H5Screate_simple(1, dsdims, NULL);
VRFY_G((mem_dataspace >= 0), "mem_dataspace create succeeded");
}
crp_plist = H5Pcreate(H5P_DATASET_CREATE);
VRFY_G((crp_plist >= 0), "");
/* Set up chunk information. */
chunk_dims[0] = dims[0] / (hsize_t)chunk_factor;
/* to decrease the testing time, maintain bigger chunk size */
(chunk_factor == 1) ? (chunk_dims[1] = space_dim2) : (chunk_dims[1] = space_dim2 / 2);
status = H5Pset_chunk(crp_plist, 2, chunk_dims);
VRFY_G((status >= 0), "chunk creation property list succeeded");
dataset = H5Dcreate2(file, DSET_COLLECTIVE_CHUNK_NAME, H5T_NATIVE_INT, file_dataspace, H5P_DEFAULT,
crp_plist, H5P_DEFAULT);
VRFY_G((dataset >= 0), "dataset created succeeded");
status = H5Pclose(crp_plist);
VRFY_G((status >= 0), "");
/*put some trivial data in the data array */
ccdataset_fill(start, stride, count, block, data_array1, mem_selection);
MESG("data_array initialized");
switch (file_selection) {
case HYPER:
status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(file_dataspace);
VRFY_G((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(file_dataspace);
VRFY_G((status >= 0), "H5Sselect_all succeeded");
break;
}
switch (mem_selection) {
case HYPER:
status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(mem_dataspace);
VRFY_G((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(mem_dataspace);
VRFY_G((status >= 0), "H5Sselect_all succeeded");
break;
}
/* set up the collective transfer property list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((status >= 0), "MPIO collective transfer property succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
status = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((status >= 0), "set independent IO collectively succeeded");
}
switch (api_option) {
case API_LINK_HARD:
status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist, H5FD_MPIO_CHUNK_ONE_IO);
VRFY_G((status >= 0), "collective chunk optimization succeeded");
break;
case API_MULTI_HARD:
status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist, H5FD_MPIO_CHUNK_MULTI_IO);
VRFY_G((status >= 0), "collective chunk optimization succeeded ");
break;
case API_LINK_TRUE:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 2);
VRFY_G((status >= 0), "collective chunk optimization set chunk number succeeded");
break;
case API_LINK_FALSE:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 6);
VRFY_G((status >= 0), "collective chunk optimization set chunk number succeeded");
break;
case API_MULTI_COLL:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 8); /* make sure it is using multi-chunk IO */
VRFY_G((status >= 0), "collective chunk optimization set chunk number succeeded");
status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist, 50);
VRFY_G((status >= 0), "collective chunk optimization set chunk ratio succeeded");
break;
case API_MULTI_IND:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 8); /* make sure it is using multi-chunk IO */
VRFY_G((status >= 0), "collective chunk optimization set chunk number succeeded");
status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist, 100);
VRFY_G((status >= 0), "collective chunk optimization set chunk ratio succeeded");
break;
default:;
}
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
if (facc_type == FACC_MPIO) {
switch (api_option) {
case API_LINK_HARD:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_HARD:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
case API_LINK_TRUE:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
case API_LINK_FALSE:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_COLL:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME,
H5D_XFER_COLL_CHUNK_SIZE, &prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_IND:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY_G((status >= 0), "testing property list inserted succeeded");
break;
default:;
}
}
#endif
/* write data collectively */
status = H5Dwrite(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY_G((status >= 0), "dataset write succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
if (facc_type == FACC_MPIO) {
switch (api_option) {
case API_LINK_HARD:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0), "API to set LINK COLLECTIVE IO directly succeeded");
break;
case API_MULTI_HARD:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0), "API to set MULTI-CHUNK COLLECTIVE IO optimization succeeded");
break;
case API_LINK_TRUE:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0), "API to set LINK COLLECTIVE IO succeeded");
break;
case API_LINK_FALSE:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0), "API to set LINK IO transferring to multi-chunk IO succeeded");
break;
case API_MULTI_COLL:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0), "API to set MULTI-CHUNK COLLECTIVE IO with optimization succeeded");
break;
case API_MULTI_IND:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, &prop_value);
VRFY_G((status >= 0), "testing property list get succeeded");
VRFY_G((prop_value == 0),
"API to set MULTI-CHUNK IO transferring to independent IO succeeded");
break;
default:;
}
}
#endif
status = H5Dclose(dataset);
VRFY_G((status >= 0), "");
status = H5Pclose(xfer_plist);
VRFY_G((status >= 0), "property list closed");
status = H5Sclose(file_dataspace);
VRFY_G((status >= 0), "");
status = H5Sclose(mem_dataspace);
VRFY_G((status >= 0), "");
status = H5Fclose(file);
VRFY_G((status >= 0), "");
if (data_array1)
HDfree(data_array1);
/* Use collective read to verify the correctness of collective write. */
/* allocate memory for data buffer */
data_array1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY_G((data_array1 != NULL), "data_array1 malloc succeeded");
/* allocate memory for data buffer */
data_origin1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY_G((data_origin1 != NULL), "data_origin1 malloc succeeded");
acc_plist = create_faccess_plist(comm, info, facc_type);
VRFY_G((acc_plist >= 0), "MPIO creation property list succeeded");
file = H5Fopen(FILENAME[0], H5F_ACC_RDONLY, acc_plist);
VRFY_G((file >= 0), "H5Fcreate succeeded");
status = H5Pclose(acc_plist);
VRFY_G((status >= 0), "");
/* open the collective dataset*/
dataset = H5Dopen2(file, DSET_COLLECTIVE_CHUNK_NAME, H5P_DEFAULT);
VRFY_G((dataset >= 0), "");
/* set up dimensions of the slab this process accesses */
ccslab_set(mpi_rank_g, mpi_size_g, start, count, stride, block, select_factor);
/* obtain the file and mem dataspace*/
file_dataspace = H5Dget_space(dataset);
VRFY_G((file_dataspace >= 0), "");
if (ALL != mem_selection) {
mem_dataspace = H5Dget_space(dataset);
VRFY_G((mem_dataspace >= 0), "");
}
else {
/* Warning: H5Screate_simple requires an array of hsize_t elements
* even if we only pass only a single value. Attempting anything else
* appears to cause problems with 32 bit compilers.
*/
hsize_t dsdims[1] = {num_points};
mem_dataspace = H5Screate_simple(1, dsdims, NULL);
VRFY_G((mem_dataspace >= 0), "mem_dataspace create succeeded");
}
switch (file_selection) {
case HYPER:
status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(file_dataspace);
VRFY_G((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(file_dataspace);
VRFY_G((status >= 0), "H5Sselect_all succeeded");
break;
}
switch (mem_selection) {
case HYPER:
status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY_G((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY_G((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(mem_dataspace);
VRFY_G((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(mem_dataspace);
VRFY_G((status >= 0), "H5Sselect_all succeeded");
break;
}
/* fill dataset with test data */
ccdataset_fill(start, stride, count, block, data_origin1, mem_selection);
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY_G((xfer_plist >= 0), "");
status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY_G((status >= 0), "MPIO collective transfer property succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
status = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY_G((status >= 0), "set independent IO collectively succeeded");
}
status = H5Dread(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY_G((status >= 0), "dataset read succeeded");
/* verify the read data with original expected data */
status = ccdataset_vrfy(start, count, stride, block, data_array1, data_origin1, mem_selection);
if (status)
nerrors++;
status = H5Pclose(xfer_plist);
VRFY_G((status >= 0), "property list closed");
/* close dataset collectively */
status = H5Dclose(dataset);
VRFY_G((status >= 0), "H5Dclose");
/* release all IDs created */
status = H5Sclose(file_dataspace);
VRFY_G((status >= 0), "H5Sclose");
status = H5Sclose(mem_dataspace);
VRFY_G((status >= 0), "H5Sclose");
/* close the file collectively */
status = H5Fclose(file);
VRFY_G((status >= 0), "H5Fclose");
/* release data buffers */
if (coords)
HDfree(coords);
if (data_array1)
HDfree(data_array1);
if (data_origin1)
HDfree(data_origin1);
}
int
main(int argc, char **argv)
{
hid_t acc_plist = H5I_INVALID_HID;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size_g);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank_g);
/* Attempt to turn off atexit post processing so that in case errors
* happen during the test and the process is aborted, it will not get
* hang in the atexit post processing in which it may try to make MPI
* calls. By then, MPI calls may not work.
*/
if (H5dont_atexit() < 0)
HDprintf("Failed to turn off atexit processing. Continue.\n");
/* set alarm. */
/* TestAlarmOn(); */
acc_plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
/* Get the capability flag of the VOL connector being used */
if (H5Pget_vol_cap_flags(acc_plist, &vol_cap_flags_g) < 0) {
if (MAIN_PROCESS)
HDprintf("Failed to get the capability flag of the VOL connector being used\n");
MPI_Finalize();
return 0;
}
/* Make sure the connector supports the API functions being tested. This test only
* uses a few API functions, such as H5Fcreate/open/close/delete, H5Dcreate/write/read/close,
* and H5Dget_space. */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAIN_PROCESS)
HDprintf(
"API functions for basic file, dataset basic or more aren't supported with this connector\n");
MPI_Finalize();
return 0;
}
dataset_big_write();
MPI_Barrier(MPI_COMM_WORLD);
dataset_big_read();
MPI_Barrier(MPI_COMM_WORLD);
coll_chunk1();
MPI_Barrier(MPI_COMM_WORLD);
coll_chunk2();
MPI_Barrier(MPI_COMM_WORLD);
coll_chunk3();
MPI_Barrier(MPI_COMM_WORLD);
single_rank_independent_io();
/* turn off alarm */
/* TestAlarmOff(); */
if (mpi_rank_g == 0) {
hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fapl_mpio(fapl_id, MPI_COMM_SELF, MPI_INFO_NULL);
H5E_BEGIN_TRY
{
H5Fdelete(FILENAME[0], fapl_id);
H5Fdelete(FILENAME[1], fapl_id);
}
H5E_END_TRY;
H5Pclose(fapl_id);
}
H5Pclose(acc_plist);
/* close HDF5 library */
H5close();
MPI_Finalize();
return 0;
}
+512
View File
@@ -0,0 +1,512 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* This verifies if the storage space allocation methods are compatible between
* serial and parallel modes.
*
* Created by: Christian Chilan and Albert Cheng
* Date: 2006/05/25
*/
#include "hdf5.h"
#include "testphdf5.h"
static int mpi_size, mpi_rank;
#define DSET_NAME "ExtendibleArray"
#define CHUNK_SIZE 1000 /* #elements per chunk */
#define CHUNK_FACTOR 200 /* default dataset size in terms of chunks */
#define CLOSE 1
#define NO_CLOSE 0
#if 0
static MPI_Offset
get_filesize(const char *filename)
{
int mpierr;
MPI_File fd;
MPI_Offset filesize;
mpierr = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fd);
VRFY((mpierr == MPI_SUCCESS), "");
mpierr = MPI_File_get_size(fd, &filesize);
VRFY((mpierr == MPI_SUCCESS), "");
mpierr = MPI_File_close(&fd);
VRFY((mpierr == MPI_SUCCESS), "");
return (filesize);
}
#endif
typedef enum write_pattern { none, sec_last, all } write_type;
typedef enum access_ { write_all, open_only, extend_only } access_type;
/*
* This creates a dataset serially with chunks, each of CHUNK_SIZE
* elements. The allocation time is set to H5D_ALLOC_TIME_EARLY. Another
* routine will open this in parallel for extension test.
*/
static void
create_chunked_dataset(const char *filename, int chunk_factor, write_type write_pattern)
{
hid_t file_id, dataset; /* handles */
hid_t dataspace, memspace;
hid_t cparms;
hsize_t dims[1];
hsize_t maxdims[1] = {H5S_UNLIMITED};
hsize_t chunk_dims[1] = {CHUNK_SIZE};
hsize_t count[1];
hsize_t stride[1];
hsize_t block[1];
hsize_t offset[1]; /* Selection offset within dataspace */
/* Variables used in reading data back */
char buffer[CHUNK_SIZE];
long nchunks;
herr_t hrc;
#if 0
MPI_Offset filesize, /* actual file size */
est_filesize; /* estimated file size */
#endif
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Only MAINPROCESS should create the file. Others just wait. */
if (MAINPROCESS) {
nchunks = chunk_factor * mpi_size;
dims[0] = (hsize_t)(nchunks * CHUNK_SIZE);
/* Create the data space with unlimited dimensions. */
dataspace = H5Screate_simple(1, dims, maxdims);
VRFY((dataspace >= 0), "");
memspace = H5Screate_simple(1, chunk_dims, NULL);
VRFY((memspace >= 0), "");
/* Create a new file. If file exists its contents will be overwritten. */
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
VRFY((file_id >= 0), "H5Fcreate");
/* Modify dataset creation properties, i.e. enable chunking */
cparms = H5Pcreate(H5P_DATASET_CREATE);
VRFY((cparms >= 0), "");
hrc = H5Pset_alloc_time(cparms, H5D_ALLOC_TIME_EARLY);
VRFY((hrc >= 0), "");
hrc = H5Pset_chunk(cparms, 1, chunk_dims);
VRFY((hrc >= 0), "");
/* Create a new dataset within the file using cparms creation properties. */
dataset =
H5Dcreate2(file_id, DSET_NAME, H5T_NATIVE_UCHAR, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT);
VRFY((dataset >= 0), "");
if (write_pattern == sec_last) {
HDmemset(buffer, 100, CHUNK_SIZE);
count[0] = 1;
stride[0] = 1;
block[0] = chunk_dims[0];
offset[0] = (hsize_t)(nchunks - 2) * chunk_dims[0];
hrc = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, stride, count, block);
VRFY((hrc >= 0), "");
/* Write sec_last chunk */
hrc = H5Dwrite(dataset, H5T_NATIVE_UCHAR, memspace, dataspace, H5P_DEFAULT, buffer);
VRFY((hrc >= 0), "H5Dwrite");
} /* end if */
/* Close resources */
hrc = H5Dclose(dataset);
VRFY((hrc >= 0), "");
dataset = -1;
hrc = H5Sclose(dataspace);
VRFY((hrc >= 0), "");
hrc = H5Sclose(memspace);
VRFY((hrc >= 0), "");
hrc = H5Pclose(cparms);
VRFY((hrc >= 0), "");
hrc = H5Fclose(file_id);
VRFY((hrc >= 0), "");
file_id = -1;
#if 0
/* verify file size */
filesize = get_filesize(filename);
est_filesize = (MPI_Offset)nchunks * (MPI_Offset)CHUNK_SIZE * (MPI_Offset)sizeof(unsigned char);
VRFY((filesize >= est_filesize), "file size check");
#endif
}
/* Make sure all processes are done before exiting this routine. Otherwise,
* other tests may start and change the test data file before some processes
* of this test are still accessing the file.
*/
MPI_Barrier(MPI_COMM_WORLD);
}
/*
* This program performs three different types of parallel access. It writes on
* the entire dataset, it extends the dataset to nchunks*CHUNK_SIZE, and it only
* opens the dataset. At the end, it verifies the size of the dataset to be
* consistent with argument 'chunk_factor'.
*/
static void
parallel_access_dataset(const char *filename, int chunk_factor, access_type action, hid_t *file_id,
hid_t *dataset)
{
/* HDF5 gubbins */
hid_t memspace, dataspace; /* HDF5 file identifier */
hid_t access_plist; /* HDF5 ID for file access property list */
herr_t hrc; /* HDF5 return code */
hsize_t size[1];
hsize_t chunk_dims[1] = {CHUNK_SIZE};
hsize_t count[1];
hsize_t stride[1];
hsize_t block[1];
hsize_t offset[1]; /* Selection offset within dataspace */
hsize_t dims[1];
hsize_t maxdims[1];
/* Variables used in reading data back */
char buffer[CHUNK_SIZE];
int i;
long nchunks;
#if 0
/* MPI Gubbins */
MPI_Offset filesize, /* actual file size */
est_filesize; /* estimated file size */
#endif
/* Initialize MPI */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
nchunks = chunk_factor * mpi_size;
/* Set up MPIO file access property lists */
access_plist = H5Pcreate(H5P_FILE_ACCESS);
VRFY((access_plist >= 0), "");
hrc = H5Pset_fapl_mpio(access_plist, MPI_COMM_WORLD, MPI_INFO_NULL);
VRFY((hrc >= 0), "");
/* Open the file */
if (*file_id < 0) {
*file_id = H5Fopen(filename, H5F_ACC_RDWR, access_plist);
VRFY((*file_id >= 0), "");
}
/* Open dataset*/
if (*dataset < 0) {
*dataset = H5Dopen2(*file_id, DSET_NAME, H5P_DEFAULT);
VRFY((*dataset >= 0), "");
}
/* Make sure all processes are done before continuing. Otherwise, one
* process could change the dataset extent before another finishes opening
* it, resulting in only some of the processes calling H5Dset_extent(). */
MPI_Barrier(MPI_COMM_WORLD);
memspace = H5Screate_simple(1, chunk_dims, NULL);
VRFY((memspace >= 0), "");
dataspace = H5Dget_space(*dataset);
VRFY((dataspace >= 0), "");
size[0] = (hsize_t)nchunks * CHUNK_SIZE;
switch (action) {
/* all chunks are written by all the processes in an interleaved way*/
case write_all:
HDmemset(buffer, mpi_rank + 1, CHUNK_SIZE);
count[0] = 1;
stride[0] = 1;
block[0] = chunk_dims[0];
for (i = 0; i < nchunks / mpi_size; i++) {
offset[0] = (hsize_t)(i * mpi_size + mpi_rank) * chunk_dims[0];
hrc = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, stride, count, block);
VRFY((hrc >= 0), "");
/* Write the buffer out */
hrc = H5Dwrite(*dataset, H5T_NATIVE_UCHAR, memspace, dataspace, H5P_DEFAULT, buffer);
VRFY((hrc >= 0), "H5Dwrite");
}
break;
/* only extends the dataset */
case extend_only:
/* check if new size is larger than old size */
hrc = H5Sget_simple_extent_dims(dataspace, dims, maxdims);
VRFY((hrc >= 0), "");
/* Extend dataset*/
if (size[0] > dims[0]) {
hrc = H5Dset_extent(*dataset, size);
VRFY((hrc >= 0), "");
}
break;
/* only opens the *dataset */
case open_only:
break;
default:
HDassert(0);
}
/* Close up */
hrc = H5Dclose(*dataset);
VRFY((hrc >= 0), "");
*dataset = -1;
hrc = H5Sclose(dataspace);
VRFY((hrc >= 0), "");
hrc = H5Sclose(memspace);
VRFY((hrc >= 0), "");
hrc = H5Fclose(*file_id);
VRFY((hrc >= 0), "");
*file_id = -1;
#if 0
/* verify file size */
filesize = get_filesize(filename);
est_filesize = (MPI_Offset)nchunks * (MPI_Offset)CHUNK_SIZE * (MPI_Offset)sizeof(unsigned char);
VRFY((filesize >= est_filesize), "file size check");
#endif
/* Can close some plists */
hrc = H5Pclose(access_plist);
VRFY((hrc >= 0), "");
/* Make sure all processes are done before exiting this routine. Otherwise,
* other tests may start and change the test data file before some processes
* of this test are still accessing the file.
*/
MPI_Barrier(MPI_COMM_WORLD);
}
/*
* This routine verifies the data written in the dataset. It does one of the
* three cases according to the value of parameter `write_pattern'.
* 1. it returns correct fill values though the dataset has not been written;
* 2. it still returns correct fill values though only a small part is written;
* 3. it returns correct values when the whole dataset has been written in an
* interleaved pattern.
*/
static void
verify_data(const char *filename, int chunk_factor, write_type write_pattern, int vclose, hid_t *file_id,
hid_t *dataset)
{
/* HDF5 gubbins */
hid_t dataspace, memspace; /* HDF5 file identifier */
hid_t access_plist; /* HDF5 ID for file access property list */
herr_t hrc; /* HDF5 return code */
hsize_t chunk_dims[1] = {CHUNK_SIZE};
hsize_t count[1];
hsize_t stride[1];
hsize_t block[1];
hsize_t offset[1]; /* Selection offset within dataspace */
/* Variables used in reading data back */
char buffer[CHUNK_SIZE];
int value, i;
int index_l;
long nchunks;
/* Initialize MPI */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
nchunks = chunk_factor * mpi_size;
/* Set up MPIO file access property lists */
access_plist = H5Pcreate(H5P_FILE_ACCESS);
VRFY((access_plist >= 0), "");
hrc = H5Pset_fapl_mpio(access_plist, MPI_COMM_WORLD, MPI_INFO_NULL);
VRFY((hrc >= 0), "");
/* Open the file */
if (*file_id < 0) {
*file_id = H5Fopen(filename, H5F_ACC_RDWR, access_plist);
VRFY((*file_id >= 0), "");
}
/* Open dataset*/
if (*dataset < 0) {
*dataset = H5Dopen2(*file_id, DSET_NAME, H5P_DEFAULT);
VRFY((*dataset >= 0), "");
}
memspace = H5Screate_simple(1, chunk_dims, NULL);
VRFY((memspace >= 0), "");
dataspace = H5Dget_space(*dataset);
VRFY((dataspace >= 0), "");
/* all processes check all chunks. */
count[0] = 1;
stride[0] = 1;
block[0] = chunk_dims[0];
for (i = 0; i < nchunks; i++) {
/* reset buffer values */
HDmemset(buffer, -1, CHUNK_SIZE);
offset[0] = (hsize_t)i * chunk_dims[0];
hrc = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, stride, count, block);
VRFY((hrc >= 0), "");
/* Read the chunk */
hrc = H5Dread(*dataset, H5T_NATIVE_UCHAR, memspace, dataspace, H5P_DEFAULT, buffer);
VRFY((hrc >= 0), "H5Dread");
/* set expected value according the write pattern */
switch (write_pattern) {
case all:
value = i % mpi_size + 1;
break;
case none:
value = 0;
break;
case sec_last:
if (i == nchunks - 2)
value = 100;
else
value = 0;
break;
default:
HDassert(0);
}
/* verify content of the chunk */
for (index_l = 0; index_l < CHUNK_SIZE; index_l++)
VRFY((buffer[index_l] == value), "data verification");
}
hrc = H5Sclose(dataspace);
VRFY((hrc >= 0), "");
hrc = H5Sclose(memspace);
VRFY((hrc >= 0), "");
/* Can close some plists */
hrc = H5Pclose(access_plist);
VRFY((hrc >= 0), "");
/* Close up */
if (vclose) {
hrc = H5Dclose(*dataset);
VRFY((hrc >= 0), "");
*dataset = -1;
hrc = H5Fclose(*file_id);
VRFY((hrc >= 0), "");
*file_id = -1;
}
/* Make sure all processes are done before exiting this routine. Otherwise,
* other tests may start and change the test data file before some processes
* of this test are still accessing the file.
*/
MPI_Barrier(MPI_COMM_WORLD);
}
/*
* Test following possible scenarios,
* Case 1:
* Sequential create a file and dataset with H5D_ALLOC_TIME_EARLY and large
* size, no write, close, reopen in parallel, read to verify all return
* the fill value.
* Case 2:
* Sequential create a file and dataset with H5D_ALLOC_TIME_EARLY but small
* size, no write, close, reopen in parallel, extend to large size, then close,
* then reopen in parallel and read to verify all return the fill value.
* Case 3:
* Sequential create a file and dataset with H5D_ALLOC_TIME_EARLY and large
* size, write just a small part of the dataset (second to the last), close,
* then reopen in parallel, read to verify all return the fill value except
* those small portion that has been written. Without closing it, writes
* all parts of the dataset in a interleave pattern, close it, and reopen
* it, read to verify all data are as written.
*/
void
test_chunk_alloc(void)
{
const char *filename;
hid_t file_id, dataset;
file_id = dataset = -1;
/* Initialize MPI */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend Chunked allocation test on file %s\n", filename);
/* Case 1 */
/* Create chunked dataset without writing anything.*/
create_chunked_dataset(filename, CHUNK_FACTOR, none);
/* reopen dataset in parallel and check for file size */
parallel_access_dataset(filename, CHUNK_FACTOR, open_only, &file_id, &dataset);
/* reopen dataset in parallel, read and verify the data */
verify_data(filename, CHUNK_FACTOR, none, CLOSE, &file_id, &dataset);
/* Case 2 */
/* Create chunked dataset without writing anything */
create_chunked_dataset(filename, 20, none);
/* reopen dataset in parallel and only extend it */
parallel_access_dataset(filename, CHUNK_FACTOR, extend_only, &file_id, &dataset);
/* reopen dataset in parallel, read and verify the data */
verify_data(filename, CHUNK_FACTOR, none, CLOSE, &file_id, &dataset);
/* Case 3 */
/* Create chunked dataset and write in the second to last chunk */
create_chunked_dataset(filename, CHUNK_FACTOR, sec_last);
/* Reopen dataset in parallel, read and verify the data. The file and dataset are not closed*/
verify_data(filename, CHUNK_FACTOR, sec_last, NO_CLOSE, &file_id, &dataset);
/* All processes write in all the chunks in a interleaved way */
parallel_access_dataset(filename, CHUNK_FACTOR, write_all, &file_id, &dataset);
/* reopen dataset in parallel, read and verify the data */
verify_data(filename, CHUNK_FACTOR, all, CLOSE, &file_id, &dataset);
}
+1417
View File
@@ -0,0 +1,1417 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "hdf5.h"
#include "testphdf5.h"
#define HYPER 1
#define POINT 2
#define ALL 3
/* some commonly used routines for collective chunk IO tests*/
static void ccslab_set(int mpi_rank, int mpi_size, hsize_t start[], hsize_t count[], hsize_t stride[],
hsize_t block[], int mode);
static void ccdataset_fill(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[],
DATATYPE *dataset, int mem_selection);
static void ccdataset_print(hsize_t start[], hsize_t block[], DATATYPE *dataset);
static int ccdataset_vrfy(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[],
DATATYPE *dataset, DATATYPE *original, int mem_selection);
static void coll_chunktest(const char *filename, int chunk_factor, int select_factor, int api_option,
int file_selection, int mem_selection, int mode);
/*-------------------------------------------------------------------------
* Function: coll_chunk1
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with a single chunk
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: One big singular selection inside one chunk
* Two dimensions,
*
* dim1 = SPACE_DIM1(5760)*mpi_size
* dim2 = SPACE_DIM2(3)
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1(5760)
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
* ------------------------------------------------------------------------
*/
void
coll_chunk1(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk2
*
* Purpose: Wrapper to test the collective chunk IO for regular DISJOINT
selection with a single chunk
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: many disjoint selections inside one chunk
* Two dimensions,
*
* dim1 = SPACE_DIM1*mpi_size(5760)
* dim2 = SPACE_DIM2(3)
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 3 for all dimensions
* count0 = SPACE_DIM1/stride0(5760/3)
* count1 = SPACE_DIM2/stride(3/3 = 1)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk2(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk3
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2(3)
* chunk_dim1 = SPACE_DIM1
* chunk_dim2 = dim2/2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk3(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_size;
int mpi_rank;
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk4
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk4(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 1, BYROW_SELECTNONE, API_NONE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk4
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk5(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk6
*
* Purpose: Test direct request for multi-chunk-io.
* Wrapper to test the collective chunk IO for regular JOINT
* selection with at least number of 2*mpi_size chunks
* Test for direct to Multi Chunk I/O.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk6(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk7
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk7(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk8
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk8(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk9
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk9(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunk10
*
* Purpose: Wrapper to test the collective chunk IO for regular JOINT
selection with at least number of 2*mpi_size chunks
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------
* Descriptions for the selection: one singular selection across many chunks
* Two dimensions, Num of chunks = 2* mpi_size
*
* dim1 = SPACE_DIM1*mpi_size
* dim2 = SPACE_DIM2
* chunk_dim1 = dim1
* chunk_dim2 = dim2
* block = 1 for all dimensions
* stride = 1 for all dimensions
* count0 = SPACE_DIM1
* count1 = SPACE_DIM2(3)
* start0 = mpi_rank*SPACE_DIM1
* start1 = 0
*
* ------------------------------------------------------------------------
*/
void
coll_chunk10(void)
{
const char *filename = PARATESTFILE /* GetTestParameters() */;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, HYPER, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, HYPER, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, ALL, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, POINT, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, HYPER, OUT_OF_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, ALL, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, POINT, IN_ORDER);
coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, HYPER, IN_ORDER);
}
/*-------------------------------------------------------------------------
* Function: coll_chunktest
*
* Purpose: The real testing routine for regular selection of collective
chunking storage
testing both write and read,
If anything fails, it may be read or write. There is no
separation test between read and write.
*
* Return: Success: 0
*
* Failure: -1
*
* Modifications:
* Remove invalid temporary property checkings for API_LINK_HARD and
* API_LINK_TRUE cases.
* Programmer: Jonathan Kim
* Date: 2012-10-10
*
* Programmer: Unknown
* July 12th, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void
coll_chunktest(const char *filename, int chunk_factor, int select_factor, int api_option, int file_selection,
int mem_selection, int mode)
{
hid_t file, dataset, file_dataspace, mem_dataspace;
hid_t acc_plist, xfer_plist, crp_plist;
hsize_t dims[RANK], chunk_dims[RANK];
int *data_array1 = NULL;
int *data_origin1 = NULL;
hsize_t start[RANK], count[RANK], stride[RANK], block[RANK];
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
unsigned prop_value;
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
int mpi_size, mpi_rank;
herr_t status;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
size_t num_points; /* for point selection */
hsize_t *coords = NULL; /* for point selection */
hsize_t current_dims; /* for point selection */
/* set up MPI parameters */
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
/* Create the data space */
acc_plist = create_faccess_plist(comm, info, facc_type);
VRFY((acc_plist >= 0), "");
file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_plist);
VRFY((file >= 0), "H5Fcreate succeeded");
status = H5Pclose(acc_plist);
VRFY((status >= 0), "");
/* setup dimensionality object */
dims[0] = (hsize_t)(SPACE_DIM1 * mpi_size);
dims[1] = SPACE_DIM2;
/* allocate memory for data buffer */
data_array1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
/* set up dimensions of the slab this process accesses */
ccslab_set(mpi_rank, mpi_size, start, count, stride, block, select_factor);
/* set up the coords array selection */
num_points = block[0] * block[1] * count[0] * count[1];
coords = (hsize_t *)HDmalloc(num_points * RANK * sizeof(hsize_t));
VRFY((coords != NULL), "coords malloc succeeded");
point_set(start, count, stride, block, num_points, coords, mode);
file_dataspace = H5Screate_simple(2, dims, NULL);
VRFY((file_dataspace >= 0), "file dataspace created succeeded");
if (ALL != mem_selection) {
mem_dataspace = H5Screate_simple(2, dims, NULL);
VRFY((mem_dataspace >= 0), "mem dataspace created succeeded");
}
else {
current_dims = num_points;
mem_dataspace = H5Screate_simple(1, &current_dims, NULL);
VRFY((mem_dataspace >= 0), "mem_dataspace create succeeded");
}
crp_plist = H5Pcreate(H5P_DATASET_CREATE);
VRFY((crp_plist >= 0), "");
/* Set up chunk information. */
chunk_dims[0] = dims[0] / (hsize_t)chunk_factor;
/* to decrease the testing time, maintain bigger chunk size */
(chunk_factor == 1) ? (chunk_dims[1] = SPACE_DIM2) : (chunk_dims[1] = SPACE_DIM2 / 2);
status = H5Pset_chunk(crp_plist, 2, chunk_dims);
VRFY((status >= 0), "chunk creation property list succeeded");
dataset = H5Dcreate2(file, DSET_COLLECTIVE_CHUNK_NAME, H5T_NATIVE_INT, file_dataspace, H5P_DEFAULT,
crp_plist, H5P_DEFAULT);
VRFY((dataset >= 0), "dataset created succeeded");
status = H5Pclose(crp_plist);
VRFY((status >= 0), "");
/*put some trivial data in the data array */
ccdataset_fill(start, stride, count, block, data_array1, mem_selection);
MESG("data_array initialized");
switch (file_selection) {
case HYPER:
status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(file_dataspace);
VRFY((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(file_dataspace);
VRFY((status >= 0), "H5Sselect_all succeeded");
break;
}
switch (mem_selection) {
case HYPER:
status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(mem_dataspace);
VRFY((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(mem_dataspace);
VRFY((status >= 0), "H5Sselect_all succeeded");
break;
}
/* set up the collective transfer property list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((status >= 0), "MPIO collective transfer property succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
status = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((status >= 0), "set independent IO collectively succeeded");
}
switch (api_option) {
case API_LINK_HARD:
status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist, H5FD_MPIO_CHUNK_ONE_IO);
VRFY((status >= 0), "collective chunk optimization succeeded");
break;
case API_MULTI_HARD:
status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist, H5FD_MPIO_CHUNK_MULTI_IO);
VRFY((status >= 0), "collective chunk optimization succeeded ");
break;
case API_LINK_TRUE:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 2);
VRFY((status >= 0), "collective chunk optimization set chunk number succeeded");
break;
case API_LINK_FALSE:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 6);
VRFY((status >= 0), "collective chunk optimization set chunk number succeeded");
break;
case API_MULTI_COLL:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 8); /* make sure it is using multi-chunk IO */
VRFY((status >= 0), "collective chunk optimization set chunk number succeeded");
status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist, 50);
VRFY((status >= 0), "collective chunk optimization set chunk ratio succeeded");
break;
case API_MULTI_IND:
status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist, 8); /* make sure it is using multi-chunk IO */
VRFY((status >= 0), "collective chunk optimization set chunk number succeeded");
status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist, 100);
VRFY((status >= 0), "collective chunk optimization set chunk ratio succeeded");
break;
default:;
}
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
if (facc_type == FACC_MPIO) {
switch (api_option) {
case API_LINK_HARD:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_HARD:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
case API_LINK_TRUE:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
case API_LINK_FALSE:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_COLL:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME,
H5D_XFER_COLL_CHUNK_SIZE, &prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
case API_MULTI_IND:
prop_value = H5D_XFER_COLL_CHUNK_DEF;
status =
H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, H5D_XFER_COLL_CHUNK_SIZE,
&prop_value, NULL, NULL, NULL, NULL, NULL, NULL);
VRFY((status >= 0), "testing property list inserted succeeded");
break;
default:;
}
}
#endif
/* write data collectively */
status = H5Dwrite(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((status >= 0), "dataset write succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
/* Only check chunk optimization mode if selection I/O is not being used -
* selection I/O bypasses this IO mode decision - it's effectively always
* multi chunk currently */
if (facc_type == FACC_MPIO && /* !H5_use_selection_io_g */ TRUE) {
switch (api_option) {
case API_LINK_HARD:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0), "API to set LINK COLLECTIVE IO directly succeeded");
break;
case API_MULTI_HARD:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0), "API to set MULTI-CHUNK COLLECTIVE IO optimization succeeded");
break;
case API_LINK_TRUE:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0), "API to set LINK COLLECTIVE IO succeeded");
break;
case API_LINK_FALSE:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0), "API to set LINK IO transferring to multi-chunk IO succeeded");
break;
case API_MULTI_COLL:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0), "API to set MULTI-CHUNK COLLECTIVE IO with optimization succeeded");
break;
case API_MULTI_IND:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, &prop_value);
VRFY((status >= 0), "testing property list get succeeded");
VRFY((prop_value == 0),
"API to set MULTI-CHUNK IO transferring to independent IO succeeded");
break;
default:;
}
}
#endif
status = H5Dclose(dataset);
VRFY((status >= 0), "");
status = H5Pclose(xfer_plist);
VRFY((status >= 0), "property list closed");
status = H5Sclose(file_dataspace);
VRFY((status >= 0), "");
status = H5Sclose(mem_dataspace);
VRFY((status >= 0), "");
status = H5Fclose(file);
VRFY((status >= 0), "");
if (data_array1)
HDfree(data_array1);
/* Use collective read to verify the correctness of collective write. */
/* allocate memory for data buffer */
data_array1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
/* allocate memory for data buffer */
data_origin1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
VRFY((data_origin1 != NULL), "data_origin1 malloc succeeded");
acc_plist = create_faccess_plist(comm, info, facc_type);
VRFY((acc_plist >= 0), "MPIO creation property list succeeded");
file = H5Fopen(filename, H5F_ACC_RDONLY, acc_plist);
VRFY((file >= 0), "H5Fcreate succeeded");
status = H5Pclose(acc_plist);
VRFY((status >= 0), "");
/* open the collective dataset*/
dataset = H5Dopen2(file, DSET_COLLECTIVE_CHUNK_NAME, H5P_DEFAULT);
VRFY((dataset >= 0), "");
/* set up dimensions of the slab this process accesses */
ccslab_set(mpi_rank, mpi_size, start, count, stride, block, select_factor);
/* obtain the file and mem dataspace*/
file_dataspace = H5Dget_space(dataset);
VRFY((file_dataspace >= 0), "");
if (ALL != mem_selection) {
mem_dataspace = H5Dget_space(dataset);
VRFY((mem_dataspace >= 0), "");
}
else {
current_dims = num_points;
mem_dataspace = H5Screate_simple(1, &current_dims, NULL);
VRFY((mem_dataspace >= 0), "mem_dataspace create succeeded");
}
switch (file_selection) {
case HYPER:
status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(file_dataspace);
VRFY((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(file_dataspace);
VRFY((status >= 0), "H5Sselect_all succeeded");
break;
}
switch (mem_selection) {
case HYPER:
status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((status >= 0), "hyperslab selection succeeded");
break;
case POINT:
if (num_points) {
status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((status >= 0), "Element selection succeeded");
}
else {
status = H5Sselect_none(mem_dataspace);
VRFY((status >= 0), "none selection succeeded");
}
break;
case ALL:
status = H5Sselect_all(mem_dataspace);
VRFY((status >= 0), "H5Sselect_all succeeded");
break;
}
/* fill dataset with test data */
ccdataset_fill(start, stride, count, block, data_origin1, mem_selection);
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((status >= 0), "MPIO collective transfer property succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
status = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((status >= 0), "set independent IO collectively succeeded");
}
status = H5Dread(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((status >= 0), "dataset read succeeded");
/* verify the read data with original expected data */
status = ccdataset_vrfy(start, count, stride, block, data_array1, data_origin1, mem_selection);
if (status)
nerrors++;
status = H5Pclose(xfer_plist);
VRFY((status >= 0), "property list closed");
/* close dataset collectively */
status = H5Dclose(dataset);
VRFY((status >= 0), "H5Dclose");
/* release all IDs created */
status = H5Sclose(file_dataspace);
VRFY((status >= 0), "H5Sclose");
status = H5Sclose(mem_dataspace);
VRFY((status >= 0), "H5Sclose");
/* close the file collectively */
status = H5Fclose(file);
VRFY((status >= 0), "H5Fclose");
/* release data buffers */
if (coords)
HDfree(coords);
if (data_array1)
HDfree(data_array1);
if (data_origin1)
HDfree(data_origin1);
}
/* Set up the selection */
static void
ccslab_set(int mpi_rank, int mpi_size, hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[],
int mode)
{
switch (mode) {
case BYROW_CONT:
/* Each process takes a slabs of rows. */
block[0] = 1;
block[1] = 1;
stride[0] = 1;
stride[1] = 1;
count[0] = SPACE_DIM1;
count[1] = SPACE_DIM2;
start[0] = (hsize_t)mpi_rank * count[0];
start[1] = 0;
break;
case BYROW_DISCONT:
/* Each process takes several disjoint blocks. */
block[0] = 1;
block[1] = 1;
stride[0] = 3;
stride[1] = 3;
count[0] = SPACE_DIM1 / (stride[0] * block[0]);
count[1] = (SPACE_DIM2) / (stride[1] * block[1]);
start[0] = (hsize_t)SPACE_DIM1 * (hsize_t)mpi_rank;
start[1] = 0;
break;
case BYROW_SELECTNONE:
/* Each process takes a slabs of rows, there are
no selections for the last process. */
block[0] = 1;
block[1] = 1;
stride[0] = 1;
stride[1] = 1;
count[0] = ((mpi_rank >= MAX(1, (mpi_size - 2))) ? 0 : SPACE_DIM1);
count[1] = SPACE_DIM2;
start[0] = (hsize_t)mpi_rank * count[0];
start[1] = 0;
break;
case BYROW_SELECTUNBALANCE:
/* The first one-third of the number of processes only
select top half of the domain, The rest will select the bottom
half of the domain. */
block[0] = 1;
count[0] = 2;
stride[0] = (hsize_t)SPACE_DIM1 * (hsize_t)mpi_size / 4 + 1;
block[1] = SPACE_DIM2;
count[1] = 1;
start[1] = 0;
stride[1] = 1;
if ((mpi_rank * 3) < (mpi_size * 2))
start[0] = (hsize_t)mpi_rank;
else
start[0] = (hsize_t)(1 + SPACE_DIM1 * mpi_size / 2 + (mpi_rank - 2 * mpi_size / 3));
break;
case BYROW_SELECTINCHUNK:
/* Each process will only select one chunk */
block[0] = 1;
count[0] = 1;
start[0] = (hsize_t)(mpi_rank * SPACE_DIM1);
stride[0] = 1;
block[1] = SPACE_DIM2;
count[1] = 1;
stride[1] = 1;
start[1] = 0;
break;
default:
/* Unknown mode. Set it to cover the whole dataset. */
block[0] = (hsize_t)SPACE_DIM1 * (hsize_t)mpi_size;
block[1] = SPACE_DIM2;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = 0;
break;
}
if (VERBOSE_MED) {
HDprintf("start[]=(%lu,%lu), count[]=(%lu,%lu), stride[]=(%lu,%lu), block[]=(%lu,%lu), total "
"datapoints=%lu\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1],
(unsigned long)(block[0] * block[1] * count[0] * count[1]));
}
}
/*
* Fill the dataset with trivial data for testing.
* Assume dimension rank is 2.
*/
static void
ccdataset_fill(hsize_t start[], hsize_t stride[], hsize_t count[], hsize_t block[], DATATYPE *dataset,
int mem_selection)
{
DATATYPE *dataptr = dataset;
DATATYPE *tmptr;
hsize_t i, j, k1, k2, k = 0;
/* put some trivial data in the data_array */
tmptr = dataptr;
/* assign the disjoint block (two-dimensional)data array value
through the pointer */
for (k1 = 0; k1 < count[0]; k1++) {
for (i = 0; i < block[0]; i++) {
for (k2 = 0; k2 < count[1]; k2++) {
for (j = 0; j < block[1]; j++) {
if (ALL != mem_selection) {
dataptr = tmptr + ((start[0] + k1 * stride[0] + i) * SPACE_DIM2 + start[1] +
k2 * stride[1] + j);
}
else {
dataptr = tmptr + k;
k++;
}
*dataptr = (DATATYPE)(k1 + k2 + i + j);
}
}
}
}
}
/*
* Print the first block of the content of the dataset.
*/
static void
ccdataset_print(hsize_t start[], hsize_t block[], DATATYPE *dataset)
{
DATATYPE *dataptr = dataset;
hsize_t i, j;
/* print the column heading */
HDprintf("Print only the first block of the dataset\n");
HDprintf("%-8s", "Cols:");
for (j = 0; j < block[1]; j++) {
HDprintf("%3lu ", (unsigned long)(start[1] + j));
}
HDprintf("\n");
/* print the slab data */
for (i = 0; i < block[0]; i++) {
HDprintf("Row %2lu: ", (unsigned long)(i + start[0]));
for (j = 0; j < block[1]; j++) {
HDprintf("%03d ", *dataptr++);
}
HDprintf("\n");
}
}
/*
* Print the content of the dataset.
*/
static int
ccdataset_vrfy(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], DATATYPE *dataset,
DATATYPE *original, int mem_selection)
{
hsize_t i, j, k1, k2, k = 0;
int vrfyerrs;
DATATYPE *dataptr, *oriptr;
/* print it if VERBOSE_MED */
if (VERBOSE_MED) {
HDprintf("dataset_vrfy dumping:::\n");
HDprintf("start(%lu, %lu), count(%lu, %lu), stride(%lu, %lu), block(%lu, %lu)\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1]);
HDprintf("original values:\n");
ccdataset_print(start, block, original);
HDprintf("compared values:\n");
ccdataset_print(start, block, dataset);
}
vrfyerrs = 0;
for (k1 = 0; k1 < count[0]; k1++) {
for (i = 0; i < block[0]; i++) {
for (k2 = 0; k2 < count[1]; k2++) {
for (j = 0; j < block[1]; j++) {
if (ALL != mem_selection) {
dataptr = dataset + ((start[0] + k1 * stride[0] + i) * SPACE_DIM2 + start[1] +
k2 * stride[1] + j);
oriptr = original + ((start[0] + k1 * stride[0] + i) * SPACE_DIM2 + start[1] +
k2 * stride[1] + j);
}
else {
dataptr = dataset + k;
oriptr = original + k;
k++;
}
if (*dataptr != *oriptr) {
if (vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED) {
HDprintf("Dataset Verify failed at [%lu][%lu]: expect %d, got %d\n",
(unsigned long)i, (unsigned long)j, *(oriptr), *(dataptr));
}
}
}
}
}
}
if (vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (vrfyerrs)
HDprintf("%d errors found in ccdataset_vrfy\n", vrfyerrs);
return (vrfyerrs);
}
+654
View File
@@ -0,0 +1,654 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* A test suite to test HDF5's collective metadata read and write capabilities,
* as enabled by making a call to H5Pset_all_coll_metadata_ops() and/or
* H5Pset_coll_metadata_write().
*/
#include "hdf5.h"
#include "testphdf5.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Define the non-participating process as the "last"
* rank to avoid any weirdness potentially caused by
* an if (mpi_rank == 0) check.
*/
#define PARTIAL_NO_SELECTION_NO_SEL_PROCESS (mpi_rank == mpi_size - 1)
#define PARTIAL_NO_SELECTION_DATASET_NAME "partial_no_selection_dset"
#define PARTIAL_NO_SELECTION_DATASET_NDIMS 2
#define PARTIAL_NO_SELECTION_Y_DIM_SCALE 5
#define PARTIAL_NO_SELECTION_X_DIM_SCALE 5
#define MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS 2
#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_COLL_THRESH_NUM 10000
#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DATASET_NAME "linked_chunk_io_sort_chunk_issue"
#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS 1
#define COLL_GHEAP_WRITE_ATTR_NELEMS 10
#define COLL_GHEAP_WRITE_ATTR_NAME "coll_gheap_write_attr"
#define COLL_GHEAP_WRITE_ATTR_DIMS 1
/*
* A test for issue HDFFV-10501. A parallel hang was reported which occurred
* in linked-chunk I/O when collective metadata reads are enabled and some ranks
* do not have any selection in a dataset's dataspace, while others do. The ranks
* which have no selection during the read/write operation called H5D__chunk_addrmap()
* to retrieve the lowest chunk address, since we require that the read/write be done
* in strictly non-decreasing order of chunk address. For version 1 and 2 B-trees,
* this caused the non-participating ranks to issue a collective MPI_Bcast() call
* which the other ranks did not issue, thus causing a hang.
*
* However, since these ranks are not actually reading/writing anything, this call
* can simply be removed and the address used for the read/write can be set to an
* arbitrary number (0 was chosen).
*/
void
test_partial_no_selection_coll_md_read(void)
{
const char *filename;
hsize_t *dataset_dims = NULL;
hsize_t max_dataset_dims[PARTIAL_NO_SELECTION_DATASET_NDIMS];
hsize_t sel_dims[1];
hsize_t chunk_dims[PARTIAL_NO_SELECTION_DATASET_NDIMS] = {PARTIAL_NO_SELECTION_Y_DIM_SCALE,
PARTIAL_NO_SELECTION_X_DIM_SCALE};
hsize_t start[PARTIAL_NO_SELECTION_DATASET_NDIMS];
hsize_t stride[PARTIAL_NO_SELECTION_DATASET_NDIMS];
hsize_t count[PARTIAL_NO_SELECTION_DATASET_NDIMS];
hsize_t block[PARTIAL_NO_SELECTION_DATASET_NDIMS];
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t dcpl_id = H5I_INVALID_HID;
hid_t dxpl_id = H5I_INVALID_HID;
hid_t fspace_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
int mpi_rank, mpi_size;
void *data = NULL;
void *read_buf = NULL;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or file flush aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl_id >= 0), "create_faccess_plist succeeded");
/*
* Even though the testphdf5 framework currently sets collective metadata reads
* on the FAPL, we call it here just to be sure this is futureproof, since
* demonstrating this issue relies upon it.
*/
VRFY((H5Pset_all_coll_metadata_ops(fapl_id, true) >= 0), "Set collective metadata reads succeeded");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate succeeded");
dataset_dims = HDmalloc(PARTIAL_NO_SELECTION_DATASET_NDIMS * sizeof(*dataset_dims));
VRFY((dataset_dims != NULL), "malloc succeeded");
dataset_dims[0] = (hsize_t)PARTIAL_NO_SELECTION_Y_DIM_SCALE * (hsize_t)mpi_size;
dataset_dims[1] = (hsize_t)PARTIAL_NO_SELECTION_X_DIM_SCALE * (hsize_t)mpi_size;
max_dataset_dims[0] = H5S_UNLIMITED;
max_dataset_dims[1] = H5S_UNLIMITED;
fspace_id = H5Screate_simple(PARTIAL_NO_SELECTION_DATASET_NDIMS, dataset_dims, max_dataset_dims);
VRFY((fspace_id >= 0), "H5Screate_simple succeeded");
/*
* Set up chunking on the dataset in order to reproduce the problem.
*/
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl_id >= 0), "H5Pcreate succeeded");
VRFY((H5Pset_chunk(dcpl_id, PARTIAL_NO_SELECTION_DATASET_NDIMS, chunk_dims) >= 0),
"H5Pset_chunk succeeded");
dset_id = H5Dcreate2(file_id, PARTIAL_NO_SELECTION_DATASET_NAME, H5T_NATIVE_INT, fspace_id, H5P_DEFAULT,
dcpl_id, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2 succeeded");
/*
* Setup hyperslab selection to split the dataset among the ranks.
*
* The ranks will write rows across the dataset.
*/
start[0] = (hsize_t)PARTIAL_NO_SELECTION_Y_DIM_SCALE * (hsize_t)mpi_rank;
start[1] = 0;
stride[0] = PARTIAL_NO_SELECTION_Y_DIM_SCALE;
stride[1] = PARTIAL_NO_SELECTION_X_DIM_SCALE;
count[0] = 1;
count[1] = (hsize_t)mpi_size;
block[0] = PARTIAL_NO_SELECTION_Y_DIM_SCALE;
block[1] = PARTIAL_NO_SELECTION_X_DIM_SCALE;
VRFY((H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) >= 0),
"H5Sselect_hyperslab succeeded");
sel_dims[0] = count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE);
mspace_id = H5Screate_simple(1, sel_dims, NULL);
VRFY((mspace_id >= 0), "H5Screate_simple succeeded");
data = HDcalloc(1, count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) *
sizeof(int));
VRFY((data != NULL), "calloc succeeded");
dxpl_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_id >= 0), "H5Pcreate succeeded");
/*
* Enable collective access for the data transfer.
*/
VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) >= 0), "H5Pset_dxpl_mpio succeeded");
VRFY((H5Dwrite(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, data) >= 0), "H5Dwrite succeeded");
VRFY((H5Fflush(file_id, H5F_SCOPE_GLOBAL) >= 0), "H5Fflush succeeded");
/*
* Ensure that linked-chunk I/O is performed since this is
* the particular code path where the issue lies and we don't
* want the library doing multi-chunk I/O behind our backs.
*/
VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_ONE_IO) >= 0),
"H5Pset_dxpl_mpio_chunk_opt succeeded");
read_buf = HDmalloc(count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) *
sizeof(int));
VRFY((read_buf != NULL), "malloc succeeded");
/*
* Make sure to call H5Sselect_none() on the non-participating process.
*/
if (PARTIAL_NO_SELECTION_NO_SEL_PROCESS) {
VRFY((H5Sselect_none(fspace_id) >= 0), "H5Sselect_none succeeded");
VRFY((H5Sselect_none(mspace_id) >= 0), "H5Sselect_none succeeded");
}
/*
* Finally have each rank read their section of data back from the dataset.
*/
VRFY((H5Dread(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, read_buf) >= 0),
"H5Dread succeeded");
/*
* Check data integrity just to be sure.
*/
if (!PARTIAL_NO_SELECTION_NO_SEL_PROCESS) {
VRFY((!HDmemcmp(data, read_buf,
count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) *
sizeof(int))),
"memcmp succeeded");
}
if (dataset_dims) {
HDfree(dataset_dims);
dataset_dims = NULL;
}
if (data) {
HDfree(data);
data = NULL;
}
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
VRFY((H5Sclose(fspace_id) >= 0), "H5Sclose succeeded");
VRFY((H5Sclose(mspace_id) >= 0), "H5Sclose succeeded");
VRFY((H5Pclose(dcpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Pclose(dxpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Dclose(dset_id) >= 0), "H5Dclose succeeded");
VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded");
}
/*
* A test for HDFFV-10562 which attempts to verify that using multi-chunk
* I/O with collective metadata reads enabled doesn't causes issues due to
* collective metadata reads being made only by process 0 in H5D__chunk_addrmap().
*
* Failure in this test may either cause a hang, or, due to how the MPI calls
* pertaining to this issue might mistakenly match up, may cause an MPI error
* message similar to:
*
* #008: H5Dmpio.c line 2546 in H5D__obtain_mpio_mode(): MPI_BCast failed
* major: Internal error (too specific to document in detail)
* minor: Some MPI function failed
* #009: H5Dmpio.c line 2546 in H5D__obtain_mpio_mode(): Message truncated, error stack:
*PMPI_Bcast(1600)..................: MPI_Bcast(buf=0x1df98e0, count=18, MPI_BYTE, root=0, comm=0x84000006)
*failed MPIR_Bcast_impl(1452).............: MPIR_Bcast(1476)..................:
*MPIR_Bcast_intra(1249)............:
*MPIR_SMP_Bcast(1088)..............:
*MPIR_Bcast_binomial(239)..........:
*MPIDI_CH3U_Receive_data_found(131): Message from rank 0 and tag 2 truncated; 2616 bytes received but buffer
*size is 18 major: Internal error (too specific to document in detail) minor: MPI Error String
*
*/
void
test_multi_chunk_io_addrmap_issue(void)
{
const char *filename;
hsize_t start[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS];
hsize_t stride[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS];
hsize_t count[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS];
hsize_t block[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS];
hsize_t dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {10, 5};
hsize_t chunk_dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {5, 5};
hsize_t max_dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {H5S_UNLIMITED, H5S_UNLIMITED};
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t dcpl_id = H5I_INVALID_HID;
hid_t dxpl_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
void *read_buf = NULL;
int mpi_rank;
int data[5][5] = {{0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}};
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or file flush aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl_id >= 0), "create_faccess_plist succeeded");
/*
* Even though the testphdf5 framework currently sets collective metadata reads
* on the FAPL, we call it here just to be sure this is futureproof, since
* demonstrating this issue relies upon it.
*/
VRFY((H5Pset_all_coll_metadata_ops(fapl_id, true) >= 0), "Set collective metadata reads succeeded");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate succeeded");
space_id = H5Screate_simple(MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS, dims, max_dims);
VRFY((space_id >= 0), "H5Screate_simple succeeded");
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl_id >= 0), "H5Pcreate succeeded");
VRFY((H5Pset_chunk(dcpl_id, MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS, chunk_dims) >= 0),
"H5Pset_chunk succeeded");
dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2 succeeded");
dxpl_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_id >= 0), "H5Pcreate succeeded");
VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) >= 0), "H5Pset_dxpl_mpio succeeded");
VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_MULTI_IO) >= 0),
"H5Pset_dxpl_mpio_chunk_opt succeeded");
start[1] = 0;
stride[0] = stride[1] = 1;
count[0] = count[1] = 5;
block[0] = block[1] = 1;
if (mpi_rank == 0)
start[0] = 0;
else
start[0] = 5;
VRFY((H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) >= 0),
"H5Sselect_hyperslab succeeded");
if (mpi_rank != 0)
VRFY((H5Sselect_none(space_id) >= 0), "H5Sselect_none succeeded");
VRFY((H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, space_id, dxpl_id, data) >= 0), "H5Dwrite succeeded");
VRFY((H5Fflush(file_id, H5F_SCOPE_GLOBAL) >= 0), "H5Fflush succeeded");
read_buf = HDmalloc(50 * sizeof(int));
VRFY((read_buf != NULL), "malloc succeeded");
VRFY((H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, read_buf) >= 0), "H5Dread succeeded");
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
VRFY((H5Sclose(space_id) >= 0), "H5Sclose succeeded");
VRFY((H5Pclose(dcpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Pclose(dxpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Dclose(dset_id) >= 0), "H5Dclose succeeded");
VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded");
}
/*
* A test for HDFFV-10562 which attempts to verify that using linked-chunk
* I/O with collective metadata reads enabled doesn't cause issues due to
* collective metadata reads being made only by process 0 in H5D__sort_chunk().
*
* NOTE: Due to the way that the threshold value which pertains to this test
* is currently calculated within HDF5, the following two conditions must be
* true to trigger the issue:
*
* Condition 1: A certain threshold ratio must be met in order to have HDF5
* obtain all chunk addresses collectively inside H5D__sort_chunk(). This is
* given by the following:
*
* (sum_chunk * 100) / (dataset_nchunks * mpi_size) >= 30%
*
* where:
* * `sum_chunk` is the combined sum of the number of chunks selected in
* the dataset by all ranks (chunks selected by more than one rank count
* individually toward the sum for each rank selecting that chunk)
* * `dataset_nchunks` is the number of chunks in the dataset (selected
* or not)
* * `mpi_size` is the size of the MPI Communicator
*
* Condition 2: `sum_chunk` divided by `mpi_size` must exceed or equal a certain
* threshold (as of this writing, 10000).
*
* To satisfy both these conditions, we #define a macro,
* LINK_CHUNK_IO_SORT_CHUNK_ISSUE_COLL_THRESH_NUM, which corresponds to the
* value of the H5D_ALL_CHUNK_ADDR_THRES_COL_NUM macro in H5Dmpio.c (the
* 10000 threshold from condition 2). We then create a dataset of that many
* chunks and have each MPI rank write to and read from a piece of every single
* chunk in the dataset. This ensures chunk utilization is the max possible
* and exceeds our 30% target ratio, while always exactly matching the numeric
* chunk threshold value of condition 2.
*
* Failure in this test may either cause a hang, or, due to how the MPI calls
* pertaining to this issue might mistakenly match up, may cause an MPI error
* message similar to:
*
* #008: H5Dmpio.c line 2338 in H5D__sort_chunk(): MPI_BCast failed
* major: Internal error (too specific to document in detail)
* minor: Some MPI function failed
* #009: H5Dmpio.c line 2338 in H5D__sort_chunk(): Other MPI error, error stack:
*PMPI_Bcast(1600)........: MPI_Bcast(buf=0x7eae610, count=320000, MPI_BYTE, root=0, comm=0x84000006) failed
*MPIR_Bcast_impl(1452)...:
*MPIR_Bcast(1476)........:
*MPIR_Bcast_intra(1249)..:
*MPIR_SMP_Bcast(1088)....:
*MPIR_Bcast_binomial(250): message sizes do not match across processes in the collective routine: Received
*2096 but expected 320000 major: Internal error (too specific to document in detail) minor: MPI Error String
*/
void
test_link_chunk_io_sort_chunk_issue(void)
{
const char *filename;
hsize_t dataset_dims[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t sel_dims[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t chunk_dims[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t start[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t stride[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t count[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hsize_t block[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS];
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t dset_id = H5I_INVALID_HID;
hid_t dcpl_id = H5I_INVALID_HID;
hid_t dxpl_id = H5I_INVALID_HID;
hid_t fspace_id = H5I_INVALID_HID;
hid_t mspace_id = H5I_INVALID_HID;
int mpi_rank, mpi_size;
void *data = NULL;
void *read_buf = NULL;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or file flush aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl_id >= 0), "create_faccess_plist succeeded");
/*
* Even though the testphdf5 framework currently sets collective metadata reads
* on the FAPL, we call it here just to be sure this is futureproof, since
* demonstrating this issue relies upon it.
*/
VRFY((H5Pset_all_coll_metadata_ops(fapl_id, true) >= 0), "Set collective metadata reads succeeded");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate succeeded");
/*
* Create a one-dimensional dataset of exactly LINK_CHUNK_IO_SORT_CHUNK_ISSUE_COLL_THRESH_NUM
* chunks, where every rank writes to a piece of every single chunk to keep utilization high.
*/
dataset_dims[0] = (hsize_t)mpi_size * (hsize_t)LINK_CHUNK_IO_SORT_CHUNK_ISSUE_COLL_THRESH_NUM;
fspace_id = H5Screate_simple(LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS, dataset_dims, NULL);
VRFY((fspace_id >= 0), "H5Screate_simple succeeded");
/*
* Set up chunking on the dataset in order to reproduce the problem.
*/
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl_id >= 0), "H5Pcreate succeeded");
/* Chunk size is equal to MPI size since each rank writes to a piece of every chunk */
chunk_dims[0] = (hsize_t)mpi_size;
VRFY((H5Pset_chunk(dcpl_id, LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS, chunk_dims) >= 0),
"H5Pset_chunk succeeded");
dset_id = H5Dcreate2(file_id, LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DATASET_NAME, H5T_NATIVE_INT, fspace_id,
H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2 succeeded");
/*
* Setup hyperslab selection to split the dataset among the ranks.
*/
start[0] = (hsize_t)mpi_rank;
stride[0] = (hsize_t)mpi_size;
count[0] = LINK_CHUNK_IO_SORT_CHUNK_ISSUE_COLL_THRESH_NUM;
block[0] = 1;
VRFY((H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) >= 0),
"H5Sselect_hyperslab succeeded");
sel_dims[0] = count[0];
mspace_id = H5Screate_simple(1, sel_dims, NULL);
VRFY((mspace_id >= 0), "H5Screate_simple succeeded");
data = HDcalloc(1, count[0] * sizeof(int));
VRFY((data != NULL), "calloc succeeded");
dxpl_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_id >= 0), "H5Pcreate succeeded");
/*
* Enable collective access for the data transfer.
*/
VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) >= 0), "H5Pset_dxpl_mpio succeeded");
VRFY((H5Dwrite(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, data) >= 0), "H5Dwrite succeeded");
VRFY((H5Fflush(file_id, H5F_SCOPE_GLOBAL) >= 0), "H5Fflush succeeded");
/*
* Ensure that linked-chunk I/O is performed since this is
* the particular code path where the issue lies and we don't
* want the library doing multi-chunk I/O behind our backs.
*/
VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_ONE_IO) >= 0),
"H5Pset_dxpl_mpio_chunk_opt succeeded");
read_buf = HDmalloc(count[0] * sizeof(int));
VRFY((read_buf != NULL), "malloc succeeded");
VRFY((H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) >= 0),
"H5Sselect_hyperslab succeeded");
sel_dims[0] = count[0];
VRFY((H5Sclose(mspace_id) >= 0), "H5Sclose succeeded");
mspace_id = H5Screate_simple(1, sel_dims, NULL);
VRFY((mspace_id >= 0), "H5Screate_simple succeeded");
/*
* Finally have each rank read their section of data back from the dataset.
*/
VRFY((H5Dread(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, read_buf) >= 0),
"H5Dread succeeded");
if (data) {
HDfree(data);
data = NULL;
}
if (read_buf) {
HDfree(read_buf);
read_buf = NULL;
}
VRFY((H5Sclose(fspace_id) >= 0), "H5Sclose succeeded");
VRFY((H5Sclose(mspace_id) >= 0), "H5Sclose succeeded");
VRFY((H5Pclose(dcpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Pclose(dxpl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Dclose(dset_id) >= 0), "H5Dclose succeeded");
VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded");
}
/*
* A test for GitHub issue #2433 which causes a collective metadata write
* of global heap data. This test is meant to ensure that global heap data
* gets correctly mapped as raw data during a collective metadata write
* using vector I/O.
*
* An assertion exists in the library that should be triggered if global
* heap data is not correctly mapped as raw data.
*/
void
test_collective_global_heap_write(void)
{
const char *filename;
hsize_t attr_dims[COLL_GHEAP_WRITE_ATTR_DIMS];
hid_t file_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t vl_type = H5I_INVALID_HID;
hid_t fspace_id = H5I_INVALID_HID;
hvl_t vl_data;
int mpi_rank, mpi_size;
int data_buf[COLL_GHEAP_WRITE_ATTR_NELEMS];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset or file flush aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl_id >= 0), "create_faccess_plist succeeded");
/*
* Even though the testphdf5 framework currently sets collective metadata
* writes on the FAPL, we call it here just to be sure this is futureproof,
* since demonstrating this issue relies upon it.
*/
VRFY((H5Pset_coll_metadata_write(fapl_id, true) >= 0), "Set collective metadata writes succeeded");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate succeeded");
attr_dims[0] = 1;
fspace_id = H5Screate_simple(COLL_GHEAP_WRITE_ATTR_DIMS, attr_dims, NULL);
VRFY((fspace_id >= 0), "H5Screate_simple succeeded");
vl_type = H5Tvlen_create(H5T_NATIVE_INT);
VRFY((vl_type >= 0), "H5Tvlen_create succeeded");
vl_data.len = COLL_GHEAP_WRITE_ATTR_NELEMS;
vl_data.p = data_buf;
/*
* Create a variable-length attribute that will get written to the global heap
*/
attr_id = H5Acreate2(file_id, COLL_GHEAP_WRITE_ATTR_NAME, vl_type, fspace_id, H5P_DEFAULT, H5P_DEFAULT);
VRFY((attr_id >= 0), "H5Acreate2 succeeded");
for (size_t i = 0; i < COLL_GHEAP_WRITE_ATTR_NELEMS; i++)
data_buf[i] = (int)i;
VRFY((H5Awrite(attr_id, vl_type, &vl_data) >= 0), "H5Awrite succeeded");
VRFY((H5Sclose(fspace_id) >= 0), "H5Sclose succeeded");
VRFY((H5Tclose(vl_type) >= 0), "H5Sclose succeeded");
VRFY((H5Aclose(attr_id) >= 0), "H5Aclose succeeded");
VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded");
VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded");
}
+4335
View File
@@ -0,0 +1,4335 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Parallel tests for datasets
*/
/*
* Example of using the parallel HDF5 library to access datasets.
*
* This program contains three major parts. Part 1 tests fixed dimension
* datasets, for both independent and collective transfer modes.
* Part 2 tests extendible datasets, for independent transfer mode
* only.
* Part 3 tests extendible datasets, for collective transfer mode
* only.
*/
#include "hdf5.h"
#include "testphdf5.h"
/*
* The following are various utility routines used by the tests.
*/
/*
* Setup the dimensions of the hyperslab.
* Two modes--by rows or by columns.
* Assume dimension rank is 2.
* BYROW divide into slabs of rows
* BYCOL divide into blocks of columns
* ZROW same as BYROW except process 0 gets 0 rows
* ZCOL same as BYCOL except process 0 gets 0 columns
*/
static void
slab_set(int mpi_rank, int mpi_size, hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[],
int mode)
{
switch (mode) {
case BYROW:
/* Each process takes a slabs of rows. */
block[0] = (hsize_t)(dim0 / mpi_size);
block[1] = (hsize_t)dim1;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank * block[0];
start[1] = 0;
if (VERBOSE_MED)
HDprintf("slab_set BYROW\n");
break;
case BYCOL:
/* Each process takes a block of columns. */
block[0] = (hsize_t)dim0;
block[1] = (hsize_t)(dim1 / mpi_size);
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = (hsize_t)mpi_rank * block[1];
if (VERBOSE_MED)
HDprintf("slab_set BYCOL\n");
break;
case ZROW:
/* Similar to BYROW except process 0 gets 0 row */
block[0] = (hsize_t)(mpi_rank ? dim0 / mpi_size : 0);
block[1] = (hsize_t)dim1;
stride[0] = (mpi_rank ? block[0] : 1); /* avoid setting stride to 0 */
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (mpi_rank ? (hsize_t)mpi_rank * block[0] : 0);
start[1] = 0;
if (VERBOSE_MED)
HDprintf("slab_set ZROW\n");
break;
case ZCOL:
/* Similar to BYCOL except process 0 gets 0 column */
block[0] = (hsize_t)dim0;
block[1] = (hsize_t)(mpi_rank ? dim1 / mpi_size : 0);
stride[0] = block[0];
stride[1] = (hsize_t)(mpi_rank ? block[1] : 1); /* avoid setting stride to 0 */
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = (mpi_rank ? (hsize_t)mpi_rank * block[1] : 0);
if (VERBOSE_MED)
HDprintf("slab_set ZCOL\n");
break;
default:
/* Unknown mode. Set it to cover the whole dataset. */
HDprintf("unknown slab_set mode (%d)\n", mode);
block[0] = (hsize_t)dim0;
block[1] = (hsize_t)dim1;
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = 0;
start[1] = 0;
if (VERBOSE_MED)
HDprintf("slab_set wholeset\n");
break;
}
if (VERBOSE_MED) {
HDprintf("start[]=(%lu,%lu), count[]=(%lu,%lu), stride[]=(%lu,%lu), block[]=(%lu,%lu), total "
"datapoints=%lu\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1],
(unsigned long)(block[0] * block[1] * count[0] * count[1]));
}
}
/*
* Setup the coordinates for point selection.
*/
void
point_set(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], size_t num_points,
hsize_t coords[], int order)
{
hsize_t i, j, k = 0, m, n, s1, s2;
HDcompile_assert(RANK == 2);
if (OUT_OF_ORDER == order)
k = (num_points * RANK) - 1;
else if (IN_ORDER == order)
k = 0;
s1 = start[0];
s2 = start[1];
for (i = 0; i < count[0]; i++)
for (j = 0; j < count[1]; j++)
for (m = 0; m < block[0]; m++)
for (n = 0; n < block[1]; n++)
if (OUT_OF_ORDER == order) {
coords[k--] = s2 + (stride[1] * j) + n;
coords[k--] = s1 + (stride[0] * i) + m;
}
else if (IN_ORDER == order) {
coords[k++] = s1 + stride[0] * i + m;
coords[k++] = s2 + stride[1] * j + n;
}
if (VERBOSE_MED) {
HDprintf("start[]=(%lu, %lu), count[]=(%lu, %lu), stride[]=(%lu, %lu), block[]=(%lu, %lu), total "
"datapoints=%lu\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1],
(unsigned long)(block[0] * block[1] * count[0] * count[1]));
k = 0;
for (i = 0; i < num_points; i++) {
HDprintf("(%d, %d)\n", (int)coords[k], (int)coords[k + 1]);
k += 2;
}
}
}
/*
* Fill the dataset with trivial data for testing.
* Assume dimension rank is 2 and data is stored contiguous.
*/
static void
dataset_fill(hsize_t start[], hsize_t block[], DATATYPE *dataset)
{
DATATYPE *dataptr = dataset;
hsize_t i, j;
/* put some trivial data in the data_array */
for (i = 0; i < block[0]; i++) {
for (j = 0; j < block[1]; j++) {
*dataptr = (DATATYPE)((i + start[0]) * 100 + (j + start[1] + 1));
dataptr++;
}
}
}
/*
* Print the content of the dataset.
*/
static void
dataset_print(hsize_t start[], hsize_t block[], DATATYPE *dataset)
{
DATATYPE *dataptr = dataset;
hsize_t i, j;
/* print the column heading */
HDprintf("%-8s", "Cols:");
for (j = 0; j < block[1]; j++) {
HDprintf("%3lu ", (unsigned long)(start[1] + j));
}
HDprintf("\n");
/* print the slab data */
for (i = 0; i < block[0]; i++) {
HDprintf("Row %2lu: ", (unsigned long)(i + start[0]));
for (j = 0; j < block[1]; j++) {
HDprintf("%03d ", *dataptr++);
}
HDprintf("\n");
}
}
/*
* Print the content of the dataset.
*/
int
dataset_vrfy(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], DATATYPE *dataset,
DATATYPE *original)
{
hsize_t i, j;
int vrfyerrs;
/* print it if VERBOSE_MED */
if (VERBOSE_MED) {
HDprintf("dataset_vrfy dumping:::\n");
HDprintf("start(%lu, %lu), count(%lu, %lu), stride(%lu, %lu), block(%lu, %lu)\n",
(unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0],
(unsigned long)count[1], (unsigned long)stride[0], (unsigned long)stride[1],
(unsigned long)block[0], (unsigned long)block[1]);
HDprintf("original values:\n");
dataset_print(start, block, original);
HDprintf("compared values:\n");
dataset_print(start, block, dataset);
}
vrfyerrs = 0;
for (i = 0; i < block[0]; i++) {
for (j = 0; j < block[1]; j++) {
if (*dataset != *original) {
if (vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED) {
HDprintf("Dataset Verify failed at [%lu][%lu](row %lu, col %lu): expect %d, got %d\n",
(unsigned long)i, (unsigned long)j, (unsigned long)(i + start[0]),
(unsigned long)(j + start[1]), *(original), *(dataset));
}
dataset++;
original++;
}
}
}
if (vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (vrfyerrs)
HDprintf("%d errors found in dataset_vrfy\n", vrfyerrs);
return (vrfyerrs);
}
/*
* Part 1.a--Independent read/write for fixed dimension datasets.
*/
/*
* Example of using the parallel HDF5 library to create two datasets
* in one HDF5 files with parallel MPIO access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset.
*/
void
dataset_writeInd(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
hsize_t dims[RANK]; /* dataset dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
const char *filename;
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Independent write test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
/* ----------------------------------------
* CREATE AN HDF5 FILE WITH PARALLEL ACCESS
* ---------------------------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* ---------------------------------------------
* Define the dimensions of the overall datasets
* and the slabs local to the MPI process.
* ------------------------------------------- */
/* setup dimensionality object */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create a dataset collectively */
dataset1 = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
/* create another dataset collectively */
dataset2 = H5Dcreate2(fid, DATASETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 succeeded");
/*
* To test the independent orders of writes between processes, all
* even number processes write to dataset1 first, then dataset2.
* All odd number processes write to dataset2 first, then dataset1.
*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* write data independently */
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
/* write data independently */
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset2 succeeded");
/* setup dimensions again to write with zero rows for process 0 */
if (VERBOSE_MED)
HDprintf("writeInd by some with zero row\n");
slab_set(mpi_rank, mpi_size, start, count, stride, block, ZROW);
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* need to make mem_dataspace to match for process 0 */
if (MAINPROCESS) {
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab mem_dataspace succeeded");
}
MESG("writeInd by some with zero row");
if ((mpi_rank / 2) * 2 != mpi_rank) {
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset1 by ZROW succeeded");
}
#ifdef BARRIER_CHECKS
MPI_Barrier(MPI_COMM_WORLD);
#endif /* BARRIER_CHECKS */
/* release dataspace ID */
H5Sclose(file_dataspace);
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
/* release all IDs created */
H5Sclose(sid);
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
}
/* Example of using the parallel HDF5 library to read a dataset */
void
dataset_readInd(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
DATATYPE *data_array1 = NULL; /* data buffer */
DATATYPE *data_origin1 = NULL; /* expected data buffer */
const char *filename;
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Independent read test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
data_origin1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_origin1 != NULL), "data_origin1 HDmalloc succeeded");
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl);
VRFY((fid >= 0), "");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* open the dataset1 collectively */
dataset1 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset1 >= 0), "");
/* open another dataset collectively */
dataset2 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset2 >= 0), "");
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
/* read data independently */
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* read data independently */
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "");
/* release all IDs created */
H5Sclose(file_dataspace);
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
if (data_origin1)
HDfree(data_origin1);
}
/*
* Part 1.b--Collective read/write for fixed dimension datasets.
*/
/*
* Example of using the parallel HDF5 library to create two datasets
* in one HDF5 file with collective parallel access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
* each process controls a hyperslab within.]
*/
void
dataset_writeAll(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2, dataset3, dataset4; /* Dataset ID */
hid_t dataset5, dataset6, dataset7; /* Dataset ID */
hid_t datatype; /* Datatype ID */
hsize_t dims[RANK]; /* dataset dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
const char *filename;
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
size_t num_points; /* for point selection */
hsize_t *coords = NULL; /* for point selection */
hsize_t current_dims; /* for point selection */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Collective write test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* set up the coords array selection */
num_points = (size_t)dim1;
coords = (hsize_t *)HDmalloc((size_t)dim1 * (size_t)RANK * sizeof(hsize_t));
VRFY((coords != NULL), "coords malloc succeeded");
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
/* -------------------
* START AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* --------------------------
* Define the dimensions of the overall datasets
* and create the dataset
* ------------------------- */
/* setup 2-D dimensionality object */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create a dataset collectively */
dataset1 = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
/* create another dataset collectively */
datatype = H5Tcopy(H5T_NATIVE_INT);
ret = H5Tset_order(datatype, H5T_ORDER_LE);
VRFY((ret >= 0), "H5Tset_order succeeded");
dataset2 = H5Dcreate2(fid, DATASETNAME2, datatype, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 2 succeeded");
/* create a third dataset collectively */
dataset3 = H5Dcreate2(fid, DATASETNAME3, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset3 >= 0), "H5Dcreate2 succeeded");
dataset5 = H5Dcreate2(fid, DATASETNAME7, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset5 >= 0), "H5Dcreate2 succeeded");
dataset6 = H5Dcreate2(fid, DATASETNAME8, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset6 >= 0), "H5Dcreate2 succeeded");
dataset7 = H5Dcreate2(fid, DATASETNAME9, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset7 >= 0), "H5Dcreate2 succeeded");
/* release 2-D space ID created */
H5Sclose(sid);
/* setup scalar dimensionality object */
sid = H5Screate(H5S_SCALAR);
VRFY((sid >= 0), "H5Screate succeeded");
/* create a fourth dataset collectively */
dataset4 = H5Dcreate2(fid, DATASETNAME4, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset4 >= 0), "H5Dcreate2 succeeded");
/* release scalar space ID created */
H5Sclose(sid);
/*
* Set up dimensions of the slab this process accesses.
*/
/* Dataset1: each process takes a block of rows. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill the local slab with some trivial data */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
MESG("writeAll by Row");
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
/* setup dimensions again to writeAll with zero rows for process 0 */
if (VERBOSE_MED)
HDprintf("writeAll by some with zero row\n");
slab_set(mpi_rank, mpi_size, start, count, stride, block, ZROW);
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* need to make mem_dataspace to match for process 0 */
if (MAINPROCESS) {
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab mem_dataspace succeeded");
}
MESG("writeAll by some with zero row");
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset1 by ZROW succeeded");
/* release all temporary handles. */
/* Could have used them for dataset2 but it is cleaner */
/* to create them again.*/
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset2: each process takes a block of columns. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill the local slab with some trivial data */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data independently */
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset2 succeeded");
/* setup dimensions again to writeAll with zero columns for process 0 */
if (VERBOSE_MED)
HDprintf("writeAll by some with zero col\n");
slab_set(mpi_rank, mpi_size, start, count, stride, block, ZCOL);
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* need to make mem_dataspace to match for process 0 */
if (MAINPROCESS) {
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab mem_dataspace succeeded");
}
MESG("writeAll by some with zero col");
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset1 by ZCOL succeeded");
/* release all temporary handles. */
/* Could have used them for dataset3 but it is cleaner */
/* to create them again.*/
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset3: each process takes a block of rows, except process zero uses "none" selection. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset3);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
if (MAINPROCESS) {
ret = H5Sselect_none(file_dataspace);
VRFY((ret >= 0), "H5Sselect_none file_dataspace succeeded");
} /* end if */
else {
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab succeeded");
} /* end else */
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
if (MAINPROCESS) {
ret = H5Sselect_none(mem_dataspace);
VRFY((ret >= 0), "H5Sselect_none mem_dataspace succeeded");
} /* end if */
/* fill the local slab with some trivial data */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
} /* end if */
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
MESG("writeAll with none");
ret = H5Dwrite(dataset3, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset3 succeeded");
/* write data collectively (with datatype conversion) */
MESG("writeAll with none");
ret = H5Dwrite(dataset3, H5T_NATIVE_UCHAR, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset3 succeeded");
/* release all temporary handles. */
/* Could have used them for dataset4 but it is cleaner */
/* to create them again.*/
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset4: each process writes no data, except process zero uses "all" selection. */
/* Additionally, these are in a scalar dataspace */
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset4);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
if (MAINPROCESS) {
ret = H5Sselect_none(file_dataspace);
VRFY((ret >= 0), "H5Sselect_all file_dataspace succeeded");
} /* end if */
else {
ret = H5Sselect_all(file_dataspace);
VRFY((ret >= 0), "H5Sselect_none succeeded");
} /* end else */
/* create a memory dataspace independently */
mem_dataspace = H5Screate(H5S_SCALAR);
VRFY((mem_dataspace >= 0), "");
if (MAINPROCESS) {
ret = H5Sselect_none(mem_dataspace);
VRFY((ret >= 0), "H5Sselect_all mem_dataspace succeeded");
} /* end if */
else {
ret = H5Sselect_all(mem_dataspace);
VRFY((ret >= 0), "H5Sselect_none succeeded");
} /* end else */
/* fill the local slab with some trivial data */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
} /* end if */
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
MESG("writeAll with scalar dataspace");
ret = H5Dwrite(dataset4, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset4 succeeded");
/* write data collectively (with datatype conversion) */
MESG("writeAll with scalar dataspace");
ret = H5Dwrite(dataset4, H5T_NATIVE_UCHAR, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset4 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
if (data_array1)
free(data_array1);
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
block[0] = 1;
block[1] = (hsize_t)dim1;
stride[0] = 1;
stride[1] = (hsize_t)dim1;
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* Dataset5: point selection in File - Hyperslab selection in Memory*/
/* create a file dataspace independently */
point_set(start, count, stride, block, num_points, coords, OUT_OF_ORDER);
file_dataspace = H5Dget_space(dataset5);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
start[0] = 0;
start[1] = 0;
mem_dataspace = H5Dget_space(dataset5);
VRFY((mem_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
ret = H5Dwrite(dataset5, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset5 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset6: point selection in File - Point selection in Memory*/
/* create a file dataspace independently */
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, OUT_OF_ORDER);
file_dataspace = H5Dget_space(dataset6);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
start[0] = 0;
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, IN_ORDER);
mem_dataspace = H5Dget_space(dataset6);
VRFY((mem_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
ret = H5Dwrite(dataset6, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset6 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset7: point selection in File - All selection in Memory*/
/* create a file dataspace independently */
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, IN_ORDER);
file_dataspace = H5Dget_space(dataset7);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
current_dims = num_points;
mem_dataspace = H5Screate_simple(1, &current_dims, NULL);
VRFY((mem_dataspace >= 0), "mem_dataspace create succeeded");
ret = H5Sselect_all(mem_dataspace);
VRFY((ret >= 0), "H5Sselect_all succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
ret = H5Dwrite(dataset7, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite dataset7 succeeded");
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/*
* All writes completed. Close datasets collectively
*/
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
ret = H5Dclose(dataset3);
VRFY((ret >= 0), "H5Dclose3 succeeded");
ret = H5Dclose(dataset4);
VRFY((ret >= 0), "H5Dclose4 succeeded");
ret = H5Dclose(dataset5);
VRFY((ret >= 0), "H5Dclose5 succeeded");
ret = H5Dclose(dataset6);
VRFY((ret >= 0), "H5Dclose6 succeeded");
ret = H5Dclose(dataset7);
VRFY((ret >= 0), "H5Dclose7 succeeded");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (coords)
HDfree(coords);
if (data_array1)
HDfree(data_array1);
}
/*
* Example of using the parallel HDF5 library to read two datasets
* in one HDF5 file with collective parallel access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
* each process controls a hyperslab within.]
*/
void
dataset_readAll(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2, dataset5, dataset6, dataset7; /* Dataset ID */
DATATYPE *data_array1 = NULL; /* data buffer */
DATATYPE *data_origin1 = NULL; /* expected data buffer */
const char *filename;
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
size_t num_points; /* for point selection */
hsize_t *coords = NULL; /* for point selection */
int i, j, k;
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Collective read test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* set up the coords array selection */
num_points = (size_t)dim1;
coords = (hsize_t *)HDmalloc((size_t)dim0 * (size_t)dim1 * RANK * sizeof(hsize_t));
VRFY((coords != NULL), "coords malloc succeeded");
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
data_origin1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_origin1 != NULL), "data_origin1 HDmalloc succeeded");
/* -------------------
* OPEN AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl);
VRFY((fid >= 0), "H5Fopen succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* --------------------------
* Open the datasets in it
* ------------------------- */
/* open the dataset1 collectively */
dataset1 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dopen2 succeeded");
/* open another dataset collectively */
dataset2 = H5Dopen2(fid, DATASETNAME2, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dopen2 2 succeeded");
/* open another dataset collectively */
dataset5 = H5Dopen2(fid, DATASETNAME7, H5P_DEFAULT);
VRFY((dataset5 >= 0), "H5Dopen2 5 succeeded");
dataset6 = H5Dopen2(fid, DATASETNAME8, H5P_DEFAULT);
VRFY((dataset6 >= 0), "H5Dopen2 6 succeeded");
dataset7 = H5Dopen2(fid, DATASETNAME9, H5P_DEFAULT);
VRFY((dataset7 >= 0), "H5Dopen2 7 succeeded");
/*
* Set up dimensions of the slab this process accesses.
*/
/* Dataset1: each process takes a block of columns. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_origin1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset1 succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* setup dimensions again to readAll with zero columns for process 0 */
if (VERBOSE_MED)
HDprintf("readAll by some with zero col\n");
slab_set(mpi_rank, mpi_size, start, count, stride, block, ZCOL);
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* need to make mem_dataspace to match for process 0 */
if (MAINPROCESS) {
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab mem_dataspace succeeded");
}
MESG("readAll by some with zero col");
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset1 by ZCOL succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* release all temporary handles. */
/* Could have used them for dataset2 but it is cleaner */
/* to create them again.*/
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* Dataset2: each process takes a block of rows. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_origin1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset2 succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* setup dimensions again to readAll with zero rows for process 0 */
if (VERBOSE_MED)
HDprintf("readAll by some with zero row\n");
slab_set(mpi_rank, mpi_size, start, count, stride, block, ZROW);
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* need to make mem_dataspace to match for process 0 */
if (MAINPROCESS) {
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab mem_dataspace succeeded");
}
MESG("readAll by some with zero row");
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset1 by ZROW succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
if (data_array1)
free(data_array1);
if (data_origin1)
free(data_origin1);
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
data_origin1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_origin1 != NULL), "data_origin1 malloc succeeded");
block[0] = 1;
block[1] = (hsize_t)dim1;
stride[0] = 1;
stride[1] = (hsize_t)dim1;
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
dataset_fill(start, block, data_origin1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_origin1);
}
/* Dataset5: point selection in memory - Hyperslab selection in file*/
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset5);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
start[0] = 0;
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, OUT_OF_ORDER);
mem_dataspace = H5Dget_space(dataset5);
VRFY((mem_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset5, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset5 succeeded");
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
if (data_array1)
free(data_array1);
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
/* Dataset6: point selection in File - Point selection in Memory*/
/* create a file dataspace independently */
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, IN_ORDER);
file_dataspace = H5Dget_space(dataset6);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
start[0] = 0;
start[1] = 0;
point_set(start, count, stride, block, num_points, coords, OUT_OF_ORDER);
mem_dataspace = H5Dget_space(dataset6);
VRFY((mem_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset6, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset6 succeeded");
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
if (ret)
nerrors++;
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
if (data_array1)
free(data_array1);
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
/* Dataset7: point selection in memory - All selection in file*/
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset7);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_all(file_dataspace);
VRFY((ret >= 0), "H5Sselect_all succeeded");
num_points = (size_t)(dim0 * dim1);
k = 0;
for (i = 0; i < dim0; i++) {
for (j = 0; j < dim1; j++) {
coords[k++] = (hsize_t)i;
coords[k++] = (hsize_t)j;
}
}
mem_dataspace = H5Dget_space(dataset7);
VRFY((mem_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
VRFY((ret >= 0), "H5Sselect_elements succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset7, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread dataset7 succeeded");
start[0] = (hsize_t)(dim0 / mpi_size * mpi_rank);
start[1] = 0;
ret = dataset_vrfy(start, count, stride, block, data_array1 + (dim0 / mpi_size * dim1 * mpi_rank),
data_origin1);
if (ret)
nerrors++;
/* release all temporary handles. */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/*
* All reads completed. Close datasets collectively
*/
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
ret = H5Dclose(dataset5);
VRFY((ret >= 0), "H5Dclose5 succeeded");
ret = H5Dclose(dataset6);
VRFY((ret >= 0), "H5Dclose6 succeeded");
ret = H5Dclose(dataset7);
VRFY((ret >= 0), "H5Dclose7 succeeded");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (coords)
HDfree(coords);
if (data_array1)
HDfree(data_array1);
if (data_origin1)
HDfree(data_origin1);
}
/*
* Part 2--Independent read/write for extendible datasets.
*/
/*
* Example of using the parallel HDF5 library to create two extendible
* datasets in one HDF5 file with independent parallel MPIO access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset.
*/
void
extend_writeInd(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
const char *filename;
hsize_t dims[RANK]; /* dataset dim sizes */
hsize_t max_dims[RANK] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* dataset maximum dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
hsize_t chunk_dims[RANK]; /* chunk sizes */
hid_t dataset_pl; /* dataset create prop. list */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK]; /* for hyperslab setting */
hsize_t stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent write test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* setup chunk-size. Make sure sizes are > 0 */
chunk_dims[0] = (hsize_t)chunkdim0;
chunk_dims[1] = (hsize_t)chunkdim1;
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
/* -------------------
* START AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* Reduce the number of metadata cache slots, so that there are cache
* collisions during the raw data I/O on the chunked dataset. This stresses
* the metadata cache and tests for cache bugs. -QAK
*/
{
int mdc_nelmts;
size_t rdcc_nelmts;
size_t rdcc_nbytes;
double rdcc_w0;
ret = H5Pget_cache(acc_tpl, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0);
VRFY((ret >= 0), "H5Pget_cache succeeded");
mdc_nelmts = 4;
ret = H5Pset_cache(acc_tpl, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0);
VRFY((ret >= 0), "H5Pset_cache succeeded");
}
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* --------------------------------------------------------------
* Define the dimensions of the overall datasets and create them.
* ------------------------------------------------------------- */
/* set up dataset storage chunk sizes and creation property list */
if (VERBOSE_MED)
HDprintf("chunks[]=%lu,%lu\n", (unsigned long)chunk_dims[0], (unsigned long)chunk_dims[1]);
dataset_pl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dataset_pl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dataset_pl, RANK, chunk_dims);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
/* setup dimensionality object */
/* start out with no rows, extend it later. */
dims[0] = dims[1] = 0;
sid = H5Screate_simple(RANK, dims, max_dims);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create an extendible dataset collectively */
dataset1 = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
/* create another extendible dataset collectively */
dataset2 = H5Dcreate2(fid, DATASETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 succeeded");
/* release resource */
H5Sclose(sid);
H5Pclose(dataset_pl);
/* -------------------------
* Test writing to dataset1
* -------------------------*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* Extend its current dim sizes before writing */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
ret = H5Dset_extent(dataset1, dims);
VRFY((ret >= 0), "H5Dset_extent succeeded");
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* write data independently */
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* release resource */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
/* -------------------------
* Test writing to dataset2
* -------------------------*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* Try write to dataset2 beyond its current dim sizes. Should fail. */
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* write data independently. Should fail. */
H5E_BEGIN_TRY
{
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
}
H5E_END_TRY
VRFY((ret < 0), "H5Dwrite failed as expected");
H5Sclose(file_dataspace);
/* Extend dataset2 and try again. Should succeed. */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
ret = H5Dset_extent(dataset2, dims);
VRFY((ret >= 0), "H5Dset_extent succeeded");
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* write data independently */
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* release resource */
ret = H5Sclose(file_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Sclose(mem_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
}
/*
* Example of using the parallel HDF5 library to create an extendable dataset
* and perform I/O on it in a way that verifies that the chunk cache is
* bypassed for parallel I/O.
*/
void
extend_writeInd2(void)
{
const char *filename;
hid_t fid; /* HDF5 file ID */
hid_t fapl; /* File access templates */
hid_t fs; /* File dataspace ID */
hid_t ms; /* Memory dataspace ID */
hid_t dataset; /* Dataset ID */
hsize_t orig_size = 10; /* Original dataset dim size */
hsize_t new_size = 20; /* Extended dataset dim size */
hsize_t one = 1;
hsize_t max_size = H5S_UNLIMITED; /* dataset maximum dim size */
hsize_t chunk_size = 16384; /* chunk size */
hid_t dcpl; /* dataset create prop. list */
int written[10], /* Data to write */
retrieved[10]; /* Data read in */
int mpi_size, mpi_rank; /* MPI settings */
int i; /* Local index variable */
herr_t ret; /* Generic return value */
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent write test #2 on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* -------------------
* START AN HDF5 FILE
* -------------------*/
/* setup file access template */
fapl = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl >= 0), "create_faccess_plist succeeded");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* --------------------------------------------------------------
* Define the dimensions of the overall datasets and create them.
* ------------------------------------------------------------- */
/* set up dataset storage chunk sizes and creation property list */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dcpl, 1, &chunk_size);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
/* setup dimensionality object */
fs = H5Screate_simple(1, &orig_size, &max_size);
VRFY((fs >= 0), "H5Screate_simple succeeded");
/* create an extendible dataset collectively */
dataset = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, fs, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreat2e succeeded");
/* release resource */
ret = H5Pclose(dcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* -------------------------
* Test writing to dataset
* -------------------------*/
/* create a memory dataspace independently */
ms = H5Screate_simple(1, &orig_size, &max_size);
VRFY((ms >= 0), "H5Screate_simple succeeded");
/* put some trivial data in the data_array */
for (i = 0; i < (int)orig_size; i++)
written[i] = i;
MESG("data array initialized");
if (VERBOSE_MED) {
MESG("writing at offset zero: ");
for (i = 0; i < (int)orig_size; i++)
HDprintf("%s%d", i ? ", " : "", written[i]);
HDprintf("\n");
}
ret = H5Dwrite(dataset, H5T_NATIVE_INT, ms, fs, H5P_DEFAULT, written);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* -------------------------
* Read initial data from dataset.
* -------------------------*/
ret = H5Dread(dataset, H5T_NATIVE_INT, ms, fs, H5P_DEFAULT, retrieved);
VRFY((ret >= 0), "H5Dread succeeded");
for (i = 0; i < (int)orig_size; i++)
if (written[i] != retrieved[i]) {
HDprintf("Line #%d: written!=retrieved: written[%d]=%d, retrieved[%d]=%d\n", __LINE__, i,
written[i], i, retrieved[i]);
nerrors++;
}
if (VERBOSE_MED) {
MESG("read at offset zero: ");
for (i = 0; i < (int)orig_size; i++)
HDprintf("%s%d", i ? ", " : "", retrieved[i]);
HDprintf("\n");
}
/* -------------------------
* Extend the dataset & retrieve new dataspace
* -------------------------*/
ret = H5Dset_extent(dataset, &new_size);
VRFY((ret >= 0), "H5Dset_extent succeeded");
ret = H5Sclose(fs);
VRFY((ret >= 0), "H5Sclose succeeded");
fs = H5Dget_space(dataset);
VRFY((fs >= 0), "H5Dget_space succeeded");
/* -------------------------
* Write to the second half of the dataset
* -------------------------*/
for (i = 0; i < (int)orig_size; i++)
written[i] = (int)orig_size + i;
MESG("data array re-initialized");
if (VERBOSE_MED) {
MESG("writing at offset 10: ");
for (i = 0; i < (int)orig_size; i++)
HDprintf("%s%d", i ? ", " : "", written[i]);
HDprintf("\n");
}
ret = H5Sselect_hyperslab(fs, H5S_SELECT_SET, &orig_size, NULL, &one, &orig_size);
VRFY((ret >= 0), "H5Sselect_hyperslab succeeded");
ret = H5Dwrite(dataset, H5T_NATIVE_INT, ms, fs, H5P_DEFAULT, written);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* -------------------------
* Read the new data
* -------------------------*/
ret = H5Dread(dataset, H5T_NATIVE_INT, ms, fs, H5P_DEFAULT, retrieved);
VRFY((ret >= 0), "H5Dread succeeded");
for (i = 0; i < (int)orig_size; i++)
if (written[i] != retrieved[i]) {
HDprintf("Line #%d: written!=retrieved: written[%d]=%d, retrieved[%d]=%d\n", __LINE__, i,
written[i], i, retrieved[i]);
nerrors++;
}
if (VERBOSE_MED) {
MESG("read at offset 10: ");
for (i = 0; i < (int)orig_size; i++)
HDprintf("%s%d", i ? ", " : "", retrieved[i]);
HDprintf("\n");
}
/* Close dataset collectively */
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
/* Close the file collectively */
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
/* Example of using the parallel HDF5 library to read an extendible dataset */
void
extend_readInd(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
hsize_t dims[RANK]; /* dataset dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
DATATYPE *data_array2 = NULL; /* data buffer */
DATATYPE *data_origin1 = NULL; /* expected data buffer */
const char *filename;
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent read test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
data_array2 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array2 != NULL), "data_array2 HDmalloc succeeded");
data_origin1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_origin1 != NULL), "data_origin1 HDmalloc succeeded");
/* -------------------
* OPEN AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl);
VRFY((fid >= 0), "");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* open the dataset1 collectively */
dataset1 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset1 >= 0), "");
/* open another dataset collectively */
dataset2 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset2 >= 0), "");
/* Try extend dataset1 which is open RDONLY. Should fail. */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sget_simple_extent_dims(file_dataspace, dims, NULL);
VRFY((ret > 0), "H5Sget_simple_extent_dims succeeded");
dims[0]++;
H5E_BEGIN_TRY
{
ret = H5Dset_extent(dataset1, dims);
}
H5E_END_TRY
VRFY((ret < 0), "H5Dset_extent failed as expected");
H5Sclose(file_dataspace);
/* Read dataset1 using BYROW pattern */
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* read data independently */
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dread succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
VRFY((ret == 0), "dataset1 read verified correct");
if (ret)
nerrors++;
H5Sclose(mem_dataspace);
H5Sclose(file_dataspace);
/* Read dataset2 using BYCOL pattern */
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* read data independently */
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array1);
VRFY((ret >= 0), "H5Dread succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
VRFY((ret == 0), "dataset2 read verified correct");
if (ret)
nerrors++;
H5Sclose(mem_dataspace);
H5Sclose(file_dataspace);
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
if (data_array2)
HDfree(data_array2);
if (data_origin1)
HDfree(data_origin1);
}
/*
* Part 3--Collective read/write for extendible datasets.
*/
/*
* Example of using the parallel HDF5 library to create two extendible
* datasets in one HDF5 file with collective parallel MPIO access support.
* The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
* Each process controls only a slab of size dim0 x dim1 within each
* dataset.
*/
void
extend_writeAll(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
const char *filename;
hsize_t dims[RANK]; /* dataset dim sizes */
hsize_t max_dims[RANK] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* dataset maximum dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
hsize_t chunk_dims[RANK]; /* chunk sizes */
hid_t dataset_pl; /* dataset create prop. list */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK]; /* for hyperslab setting */
hsize_t stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent write test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* setup chunk-size. Make sure sizes are > 0 */
chunk_dims[0] = (hsize_t)chunkdim0;
chunk_dims[1] = (hsize_t)chunkdim1;
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
/* -------------------
* START AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* Reduce the number of metadata cache slots, so that there are cache
* collisions during the raw data I/O on the chunked dataset. This stresses
* the metadata cache and tests for cache bugs. -QAK
*/
{
int mdc_nelmts;
size_t rdcc_nelmts;
size_t rdcc_nbytes;
double rdcc_w0;
ret = H5Pget_cache(acc_tpl, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0);
VRFY((ret >= 0), "H5Pget_cache succeeded");
mdc_nelmts = 4;
ret = H5Pset_cache(acc_tpl, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0);
VRFY((ret >= 0), "H5Pset_cache succeeded");
}
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* --------------------------------------------------------------
* Define the dimensions of the overall datasets and create them.
* ------------------------------------------------------------- */
/* set up dataset storage chunk sizes and creation property list */
if (VERBOSE_MED)
HDprintf("chunks[]=%lu,%lu\n", (unsigned long)chunk_dims[0], (unsigned long)chunk_dims[1]);
dataset_pl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dataset_pl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dataset_pl, RANK, chunk_dims);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
/* setup dimensionality object */
/* start out with no rows, extend it later. */
dims[0] = dims[1] = 0;
sid = H5Screate_simple(RANK, dims, max_dims);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create an extendible dataset collectively */
dataset1 = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
/* create another extendible dataset collectively */
dataset2 = H5Dcreate2(fid, DATASETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 succeeded");
/* release resource */
H5Sclose(sid);
H5Pclose(dataset_pl);
/* -------------------------
* Test writing to dataset1
* -------------------------*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* Extend its current dim sizes before writing */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
ret = H5Dset_extent(dataset1, dims);
VRFY((ret >= 0), "H5Dset_extent succeeded");
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* write data collectively */
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* release resource */
H5Sclose(file_dataspace);
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
/* -------------------------
* Test writing to dataset2
* -------------------------*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* put some trivial data in the data_array */
dataset_fill(start, block, data_array1);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Try write to dataset2 beyond its current dim sizes. Should fail. */
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* write data independently. Should fail. */
H5E_BEGIN_TRY
{
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
}
H5E_END_TRY
VRFY((ret < 0), "H5Dwrite failed as expected");
H5Sclose(file_dataspace);
/* Extend dataset2 and try again. Should succeed. */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
ret = H5Dset_extent(dataset2, dims);
VRFY((ret >= 0), "H5Dset_extent succeeded");
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* write data independently */
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* release resource */
ret = H5Sclose(file_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Sclose(mem_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Pclose(xfer_plist);
VRFY((ret >= 0), "H5Pclose succeeded");
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
}
/* Example of using the parallel HDF5 library to read an extendible dataset */
void
extend_readAll(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
const char *filename;
hsize_t dims[RANK]; /* dataset dim sizes */
DATATYPE *data_array1 = NULL; /* data buffer */
DATATYPE *data_array2 = NULL; /* data buffer */
DATATYPE *data_origin1 = NULL; /* expected data buffer */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent read test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/* allocate memory for data buffer */
data_array1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array1 != NULL), "data_array1 HDmalloc succeeded");
data_array2 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_array2 != NULL), "data_array2 HDmalloc succeeded");
data_origin1 = (DATATYPE *)HDmalloc((size_t)dim0 * (size_t)dim1 * sizeof(DATATYPE));
VRFY((data_origin1 != NULL), "data_origin1 HDmalloc succeeded");
/* -------------------
* OPEN AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl);
VRFY((fid >= 0), "");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* open the dataset1 collectively */
dataset1 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset1 >= 0), "");
/* open another dataset collectively */
dataset2 = H5Dopen2(fid, DATASETNAME1, H5P_DEFAULT);
VRFY((dataset2 >= 0), "");
/* Try extend dataset1 which is open RDONLY. Should fail. */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sget_simple_extent_dims(file_dataspace, dims, NULL);
VRFY((ret > 0), "H5Sget_simple_extent_dims succeeded");
dims[0]++;
H5E_BEGIN_TRY
{
ret = H5Dset_extent(dataset1, dims);
}
H5E_END_TRY
VRFY((ret < 0), "H5Dset_extent failed as expected");
H5Sclose(file_dataspace);
/* Read dataset1 using BYROW pattern */
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
VRFY((ret == 0), "dataset1 read verified correct");
if (ret)
nerrors++;
H5Sclose(mem_dataspace);
H5Sclose(file_dataspace);
H5Pclose(xfer_plist);
/* Read dataset2 using BYCOL pattern */
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* fill dataset with test data */
dataset_fill(start, block, data_origin1);
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(start, block, data_array1);
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* read data collectively */
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1);
VRFY((ret >= 0), "H5Dread succeeded");
/* verify the read data with original expected data */
ret = dataset_vrfy(start, count, stride, block, data_array1, data_origin1);
VRFY((ret == 0), "dataset2 read verified correct");
if (ret)
nerrors++;
H5Sclose(mem_dataspace);
H5Sclose(file_dataspace);
H5Pclose(xfer_plist);
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_array1)
HDfree(data_array1);
if (data_array2)
HDfree(data_array2);
if (data_origin1)
HDfree(data_origin1);
}
#ifdef H5_HAVE_FILTER_DEFLATE
static const char *
h5_rmprefix(const char *filename)
{
const char *ret_ptr;
if ((ret_ptr = HDstrstr(filename, ":")) == NULL)
ret_ptr = filename;
else
ret_ptr++;
return (ret_ptr);
}
/*
* Example of using the parallel HDF5 library to read a compressed
* dataset in an HDF5 file with collective parallel access support.
*/
void
compress_readAll(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t dcpl; /* Dataset creation property list */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t dataspace; /* Dataspace ID */
hid_t dataset; /* Dataset ID */
int rank = 1; /* Dataspace rank */
hsize_t dim = (hsize_t)dim0; /* Dataspace dimensions */
unsigned u; /* Local index variable */
unsigned chunk_opts; /* Chunk options */
unsigned disable_partial_chunk_filters; /* Whether filters are disabled on partial chunks */
DATATYPE *data_read = NULL; /* data buffer */
DATATYPE *data_orig = NULL; /* expected data buffer */
const char *filename;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
int mpi_size, mpi_rank;
herr_t ret; /* Generic return value */
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Collective chunked dataset read test on file %s\n", filename);
/* Retrieve MPI parameters */
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
/* Allocate data buffer */
data_orig = (DATATYPE *)HDmalloc((size_t)dim * sizeof(DATATYPE));
VRFY((data_orig != NULL), "data_origin1 HDmalloc succeeded");
data_read = (DATATYPE *)HDmalloc((size_t)dim * sizeof(DATATYPE));
VRFY((data_read != NULL), "data_array1 HDmalloc succeeded");
/* Initialize data buffers */
for (u = 0; u < dim; u++)
data_orig[u] = (DATATYPE)u;
/* Run test both with and without filters disabled on partial chunks */
for (disable_partial_chunk_filters = 0; disable_partial_chunk_filters <= 1;
disable_partial_chunk_filters++) {
/* Process zero creates the file with a compressed, chunked dataset */
if (mpi_rank == 0) {
hsize_t chunk_dim; /* Chunk dimensions */
/* Create the file */
fid = H5Fcreate(h5_rmprefix(filename), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
VRFY((fid > 0), "H5Fcreate succeeded");
/* Create property list for chunking and compression */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl > 0), "H5Pcreate succeeded");
ret = H5Pset_layout(dcpl, H5D_CHUNKED);
VRFY((ret >= 0), "H5Pset_layout succeeded");
/* Use eight chunks */
chunk_dim = dim / 8;
ret = H5Pset_chunk(dcpl, rank, &chunk_dim);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
/* Set chunk options appropriately */
if (disable_partial_chunk_filters) {
ret = H5Pget_chunk_opts(dcpl, &chunk_opts);
VRFY((ret >= 0), "H5Pget_chunk_opts succeeded");
chunk_opts |= H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS;
ret = H5Pset_chunk_opts(dcpl, chunk_opts);
VRFY((ret >= 0), "H5Pset_chunk_opts succeeded");
} /* end if */
ret = H5Pset_deflate(dcpl, 9);
VRFY((ret >= 0), "H5Pset_deflate succeeded");
/* Create dataspace */
dataspace = H5Screate_simple(rank, &dim, NULL);
VRFY((dataspace > 0), "H5Screate_simple succeeded");
/* Create dataset */
dataset =
H5Dcreate2(fid, "compressed_data", H5T_NATIVE_INT, dataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset > 0), "H5Dcreate2 succeeded");
/* Write compressed data */
ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_orig);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* Close objects */
ret = H5Pclose(dcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Sclose(dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
/* Wait for file to be created */
MPI_Barrier(comm);
/* -------------------
* OPEN AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDWR, acc_tpl);
VRFY((fid > 0), "H5Fopen succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* Open dataset with compressed chunks */
dataset = H5Dopen2(fid, "compressed_data", H5P_DEFAULT);
VRFY((dataset > 0), "H5Dopen2 succeeded");
/* Try reading & writing data */
if (dataset > 0) {
/* Create dataset transfer property list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist > 0), "H5Pcreate succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Try reading the data */
ret = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, xfer_plist, data_read);
VRFY((ret >= 0), "H5Dread succeeded");
/* Verify data read */
for (u = 0; u < dim; u++)
if (data_orig[u] != data_read[u]) {
HDprintf("Line #%d: written!=retrieved: data_orig[%u]=%d, data_read[%u]=%d\n", __LINE__,
(unsigned)u, data_orig[u], (unsigned)u, data_read[u]);
nerrors++;
}
#ifdef H5_HAVE_PARALLEL_FILTERED_WRITES
ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, xfer_plist, data_read);
VRFY((ret >= 0), "H5Dwrite succeeded");
#endif
ret = H5Pclose(xfer_plist);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
} /* end if */
/* Close file */
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
} /* end for */
/* release data buffers */
if (data_read)
HDfree(data_read);
if (data_orig)
HDfree(data_orig);
}
#endif /* H5_HAVE_FILTER_DEFLATE */
/*
* Part 4--Non-selection for chunked dataset
*/
/*
* Example of using the parallel HDF5 library to create chunked
* dataset in one HDF5 file with collective and independent parallel
* MPIO access support. The Datasets are of sizes dim0 x dim1.
* Each process controls only a slab of size dim0 x dim1 within the
* dataset with the exception that one processor selects no element.
*/
void
none_selection_chunk(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist; /* Dataset transfer properties list */
hid_t sid; /* Dataspace ID */
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* memory dataspace ID */
hid_t dataset1, dataset2; /* Dataset ID */
const char *filename;
hsize_t dims[RANK]; /* dataset dim sizes */
DATATYPE *data_origin = NULL; /* data buffer */
DATATYPE *data_array = NULL; /* data buffer */
hsize_t chunk_dims[RANK]; /* chunk sizes */
hid_t dataset_pl; /* dataset create prop. list */
hsize_t start[RANK]; /* for hyperslab setting */
hsize_t count[RANK]; /* for hyperslab setting */
hsize_t stride[RANK]; /* for hyperslab setting */
hsize_t block[RANK]; /* for hyperslab setting */
hsize_t mstart[RANK]; /* for data buffer in memory */
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Extend independent write test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
/* setup chunk-size. Make sure sizes are > 0 */
chunk_dims[0] = (hsize_t)chunkdim0;
chunk_dims[1] = (hsize_t)chunkdim1;
/* -------------------
* START AN HDF5 FILE
* -------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
/* --------------------------------------------------------------
* Define the dimensions of the overall datasets and create them.
* ------------------------------------------------------------- */
/* set up dataset storage chunk sizes and creation property list */
if (VERBOSE_MED)
HDprintf("chunks[]=%lu,%lu\n", (unsigned long)chunk_dims[0], (unsigned long)chunk_dims[1]);
dataset_pl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dataset_pl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dataset_pl, RANK, chunk_dims);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
/* setup dimensionality object */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create an extendible dataset collectively */
dataset1 = H5Dcreate2(fid, DATASETNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
/* create another extendible dataset collectively */
dataset2 = H5Dcreate2(fid, DATASETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, dataset_pl, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 succeeded");
/* release resource */
H5Sclose(sid);
H5Pclose(dataset_pl);
/* -------------------------
* Test collective writing to dataset1
* -------------------------*/
/* set up dimensions of the slab this process accesses */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
/* allocate memory for data buffer. Only allocate enough buffer for
* each processor's data. */
if (mpi_rank) {
data_origin = (DATATYPE *)HDmalloc(block[0] * block[1] * sizeof(DATATYPE));
VRFY((data_origin != NULL), "data_origin HDmalloc succeeded");
data_array = (DATATYPE *)HDmalloc(block[0] * block[1] * sizeof(DATATYPE));
VRFY((data_array != NULL), "data_array HDmalloc succeeded");
/* put some trivial data in the data_array */
mstart[0] = mstart[1] = 0;
dataset_fill(mstart, block, data_origin);
MESG("data_array initialized");
if (VERBOSE_MED) {
MESG("data_array created");
dataset_print(mstart, block, data_origin);
}
}
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* Process 0 has no selection */
if (!mpi_rank) {
ret = H5Sselect_none(mem_dataspace);
VRFY((ret >= 0), "H5Sselect_none succeeded");
}
/* create a file dataspace independently */
file_dataspace = H5Dget_space(dataset1);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* Process 0 has no selection */
if (!mpi_rank) {
ret = H5Sselect_none(file_dataspace);
VRFY((ret >= 0), "H5Sselect_none succeeded");
}
/* set up the collective transfer properties list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* write data collectively */
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_origin);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* read data independently */
ret = H5Dread(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array);
VRFY((ret >= 0), "");
/* verify the read data with original expected data */
if (mpi_rank) {
ret = dataset_vrfy(mstart, count, stride, block, data_array, data_origin);
if (ret)
nerrors++;
}
/* -------------------------
* Test independent writing to dataset2
* -------------------------*/
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_INDEPENDENT);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* write data collectively */
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_origin);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* read data independently */
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, data_array);
VRFY((ret >= 0), "");
/* verify the read data with original expected data */
if (mpi_rank) {
ret = dataset_vrfy(mstart, count, stride, block, data_array, data_origin);
if (ret)
nerrors++;
}
/* release resource */
ret = H5Sclose(file_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Sclose(mem_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Pclose(xfer_plist);
VRFY((ret >= 0), "H5Pclose succeeded");
/* close dataset collectively */
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose1 succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose2 succeeded");
/* close the file collectively */
H5Fclose(fid);
/* release data buffers */
if (data_origin)
HDfree(data_origin);
if (data_array)
HDfree(data_array);
}
/* Function: test_actual_io_mode
*
* Purpose: tests one specific case of collective I/O and checks that the
* actual_chunk_opt_mode property and the actual_io_mode
* properties in the DXPL have the correct values.
*
* Input: selection_mode: changes the way processes select data from the space, as well
* as some dxpl flags to get collective I/O to break in different ways.
*
* The relevant I/O function and expected response for each mode:
* TEST_ACTUAL_IO_MULTI_CHUNK_IND:
* H5D_mpi_chunk_collective_io, each process reports independent I/O
*
* TEST_ACTUAL_IO_MULTI_CHUNK_COL:
* H5D_mpi_chunk_collective_io, each process reports collective I/O
*
* TEST_ACTUAL_IO_MULTI_CHUNK_MIX:
* H5D_mpi_chunk_collective_io, each process reports mixed I/O
*
* TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE:
* H5D_mpi_chunk_collective_io, processes disagree. The root reports
* collective, the rest report independent I/O
*
* TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND:
* Same test TEST_ACTUAL_IO_MULTI_CHUNK_IND.
* Set directly go to multi-chunk-io without num threshold calc.
* TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL:
* Same test TEST_ACTUAL_IO_MULTI_CHUNK_COL.
* Set directly go to multi-chunk-io without num threshold calc.
*
* TEST_ACTUAL_IO_LINK_CHUNK:
* H5D_link_chunk_collective_io, processes report linked chunk I/O
*
* TEST_ACTUAL_IO_CONTIGUOUS:
* H5D__contig_collective_write or H5D__contig_collective_read
* each process reports contiguous collective I/O
*
* TEST_ACTUAL_IO_NO_COLLECTIVE:
* Simple independent I/O. This tests that the defaults are properly set.
*
* TEST_ACTUAL_IO_RESET:
* Performs collective and then independent I/O with hthe same dxpl to
* make sure the peroperty is correctly reset to the default on each use.
* Specifically, this test runs TEST_ACTUAL_IO_MULTI_CHUNK_NO_OPT_MIX_DISAGREE
* (The most complex case that works on all builds) and then performs
* an independent read and write with the same dxpls.
*
* Note: DIRECT_MULTI_CHUNK_MIX and DIRECT_MULTI_CHUNK_MIX_DISAGREE
* is not needed as they are covered by DIRECT_CHUNK_MIX and
* MULTI_CHUNK_MIX_DISAGREE cases. _DIRECT_ cases are only for testing
* path way to multi-chunk-io by H5FD_MPIO_CHUNK_MULTI_IO instead of num-threshold.
*
* Modification:
* - Refctore to remove multi-chunk-without-opimization test and update for
* testing direct to multi-chunk-io
* Programmer: Jonathan Kim
* Date: 2012-10-10
*
*
* Programmer: Jacob Gruber
* Date: 2011-04-06
*/
static void
test_actual_io_mode(int selection_mode)
{
H5D_mpio_actual_chunk_opt_mode_t actual_chunk_opt_mode_write = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
H5D_mpio_actual_chunk_opt_mode_t actual_chunk_opt_mode_read = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
H5D_mpio_actual_chunk_opt_mode_t actual_chunk_opt_mode_expected = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
H5D_mpio_actual_io_mode_t actual_io_mode_write = H5D_MPIO_NO_COLLECTIVE;
H5D_mpio_actual_io_mode_t actual_io_mode_read = H5D_MPIO_NO_COLLECTIVE;
H5D_mpio_actual_io_mode_t actual_io_mode_expected = H5D_MPIO_NO_COLLECTIVE;
const char *filename;
const char *test_name;
hbool_t direct_multi_chunk_io;
hbool_t multi_chunk_io;
hbool_t is_chunked;
hbool_t is_collective;
int mpi_size = -1;
int mpi_rank = -1;
int length;
int *buffer;
int i;
MPI_Comm mpi_comm = MPI_COMM_NULL;
MPI_Info mpi_info = MPI_INFO_NULL;
hid_t fid = -1;
hid_t sid = -1;
hid_t dataset = -1;
hid_t data_type = H5T_NATIVE_INT;
hid_t fapl = -1;
hid_t mem_space = -1;
hid_t file_space = -1;
hid_t dcpl = -1;
hid_t dxpl_write = -1;
hid_t dxpl_read = -1;
hsize_t dims[RANK];
hsize_t chunk_dims[RANK];
hsize_t start[RANK];
hsize_t stride[RANK];
hsize_t count[RANK];
hsize_t block[RANK];
char message[256];
herr_t ret;
/* Set up some flags to make some future if statements slightly more readable */
direct_multi_chunk_io = (selection_mode == TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND ||
selection_mode == TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL);
/* Note: RESET performs the same tests as MULTI_CHUNK_MIX_DISAGREE and then
* tests independent I/O
*/
multi_chunk_io =
(selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_IND ||
selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_COL ||
selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_MIX ||
selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE || selection_mode == TEST_ACTUAL_IO_RESET);
is_chunked =
(selection_mode != TEST_ACTUAL_IO_CONTIGUOUS && selection_mode != TEST_ACTUAL_IO_NO_COLLECTIVE);
is_collective = selection_mode != TEST_ACTUAL_IO_NO_COLLECTIVE;
/* Set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
MPI_Barrier(MPI_COMM_WORLD);
HDassert(mpi_size >= 1);
mpi_comm = MPI_COMM_WORLD;
mpi_info = MPI_INFO_NULL;
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
HDassert(filename != NULL);
/* Setup the file access template */
fapl = create_faccess_plist(mpi_comm, mpi_info, facc_type);
VRFY((fapl >= 0), "create_faccess_plist() succeeded");
/* Create the file */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Create the basic Space */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* Create the dataset creation plist */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "dataset creation plist created successfully");
/* If we are not testing contiguous datasets */
if (is_chunked) {
/* Set up chunk information. */
chunk_dims[0] = dims[0] / (hsize_t)mpi_size;
chunk_dims[1] = dims[1];
ret = H5Pset_chunk(dcpl, 2, chunk_dims);
VRFY((ret >= 0), "chunk creation property list succeeded");
}
/* Create the dataset */
dataset = H5Dcreate2(fid, "actual_io", data_type, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2() dataset succeeded");
/* Create the file dataspace */
file_space = H5Dget_space(dataset);
VRFY((file_space >= 0), "H5Dget_space succeeded");
/* Choose a selection method based on the type of I/O we want to occur,
* and also set up some selection-dependeent test info. */
switch (selection_mode) {
/* Independent I/O with optimization */
case TEST_ACTUAL_IO_MULTI_CHUNK_IND:
case TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND:
/* Since the dataset is chunked by row and each process selects a row,
* each process writes to a different chunk. This forces all I/O to be
* independent.
*/
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
test_name = "Multi Chunk - Independent";
actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK;
actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT;
break;
/* Collective I/O with optimization */
case TEST_ACTUAL_IO_MULTI_CHUNK_COL:
case TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL:
/* The dataset is chunked by rows, so each process takes a column which
* spans all chunks. Since the processes write non-overlapping regular
* selections to each chunk, the operation is purely collective.
*/
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
test_name = "Multi Chunk - Collective";
actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK;
if (mpi_size > 1)
actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE;
else
actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT;
break;
/* Mixed I/O with optimization */
case TEST_ACTUAL_IO_MULTI_CHUNK_MIX:
/* A chunk will be assigned collective I/O only if it is selected by each
* process. To get mixed I/O, have the root select all chunks and each
* subsequent process select the first and nth chunk. The first chunk,
* accessed by all, will be assigned collective I/O while each other chunk
* will be accessed only by the root and the nth process and will be
* assigned independent I/O. Each process will access one chunk collectively
* and at least one chunk independently, reporting mixed I/O.
*/
if (mpi_rank == 0) {
/* Select the first column */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
}
else {
/* Select the first and the nth chunk in the nth column */
block[0] = (hsize_t)(dim0 / mpi_size);
block[1] = (hsize_t)(dim1 / mpi_size);
count[0] = 2;
count[1] = 1;
stride[0] = (hsize_t)mpi_rank * block[0];
stride[1] = 1;
start[0] = 0;
start[1] = (hsize_t)mpi_rank * block[1];
}
test_name = "Multi Chunk - Mixed";
actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK;
actual_io_mode_expected = H5D_MPIO_CHUNK_MIXED;
break;
/* RESET tests that the properties are properly reset to defaults each time I/O is
* performed. To achieve this, we have RESET perform collective I/O (which would change
* the values from the defaults) followed by independent I/O (which should report the
* default values). RESET doesn't need to have a unique selection, so we reuse
* MULTI_CHUMK_MIX_DISAGREE, which was chosen because it is a complex case that works
* on all builds. The independent section of RESET can be found at the end of this function.
*/
case TEST_ACTUAL_IO_RESET:
/* Mixed I/O with optimization and internal disagreement */
case TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE:
/* A chunk will be assigned collective I/O only if it is selected by each
* process. To get mixed I/O with disagreement, assign process n to the
* first chunk and the nth chunk. The first chunk, selected by all, is
* assgigned collective I/O, while each other process gets independent I/O.
* Since the root process with only access the first chunk, it will report
* collective I/O. The subsequent processes will access the first chunk
* collectively, and their other chunk independently, reporting mixed I/O.
*/
if (mpi_rank == 0) {
/* Select the first chunk in the first column */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL);
block[0] = block[0] / (hsize_t)mpi_size;
}
else {
/* Select the first and the nth chunk in the nth column */
block[0] = (hsize_t)(dim0 / mpi_size);
block[1] = (hsize_t)(dim1 / mpi_size);
count[0] = 2;
count[1] = 1;
stride[0] = (hsize_t)mpi_rank * block[0];
stride[1] = 1;
start[0] = 0;
start[1] = (hsize_t)mpi_rank * block[1];
}
/* If the testname was not already set by the RESET case */
if (selection_mode == TEST_ACTUAL_IO_RESET)
test_name = "RESET";
else
test_name = "Multi Chunk - Mixed (Disagreement)";
actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK;
if (mpi_size > 1) {
if (mpi_rank == 0)
actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE;
else
actual_io_mode_expected = H5D_MPIO_CHUNK_MIXED;
}
else
actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT;
break;
/* Linked Chunk I/O */
case TEST_ACTUAL_IO_LINK_CHUNK:
/* Nothing special; link chunk I/O is forced in the dxpl settings. */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
test_name = "Link Chunk";
actual_chunk_opt_mode_expected = H5D_MPIO_LINK_CHUNK;
actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE;
break;
/* Contiguous Dataset */
case TEST_ACTUAL_IO_CONTIGUOUS:
/* A non overlapping, regular selection in a contiguous dataset leads to
* collective I/O */
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
test_name = "Contiguous";
actual_chunk_opt_mode_expected = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
actual_io_mode_expected = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
break;
case TEST_ACTUAL_IO_NO_COLLECTIVE:
slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW);
test_name = "Independent";
actual_chunk_opt_mode_expected = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
actual_io_mode_expected = H5D_MPIO_NO_COLLECTIVE;
break;
default:
test_name = "Undefined Selection Mode";
actual_chunk_opt_mode_expected = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
actual_io_mode_expected = H5D_MPIO_NO_COLLECTIVE;
break;
}
ret = H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* Create a memory dataspace mirroring the dataset and select the same hyperslab
* as in the file space.
*/
mem_space = H5Screate_simple(RANK, dims, NULL);
VRFY((mem_space >= 0), "mem_space created");
ret = H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* Get the number of elements in the selection */
length = dim0 * dim1;
/* Allocate and initialize the buffer */
buffer = (int *)HDmalloc(sizeof(int) * (size_t)length);
VRFY((buffer != NULL), "HDmalloc of buffer succeeded");
for (i = 0; i < length; i++)
buffer[i] = i;
/* Set up the dxpl for the write */
dxpl_write = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
/* Set collective I/O properties in the dxpl. */
if (is_collective) {
/* Request collective I/O */
ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* Set the threshold number of processes per chunk to twice mpi_size.
* This will prevent the threshold from ever being met, thus forcing
* multi chunk io instead of link chunk io.
* This is via default.
*/
if (multi_chunk_io) {
/* force multi-chunk-io by threshold */
ret = H5Pset_dxpl_mpio_chunk_opt_num(dxpl_write, (unsigned)mpi_size * 2);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_num succeeded");
/* set this to manipulate testing scenario about allocating processes
* to chunks */
ret = H5Pset_dxpl_mpio_chunk_opt_ratio(dxpl_write, (unsigned)99);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_ratio succeeded");
}
/* Set directly go to multi-chunk-io without threshold calc. */
if (direct_multi_chunk_io) {
/* set for multi chunk io by property*/
ret = H5Pset_dxpl_mpio_chunk_opt(dxpl_write, H5FD_MPIO_CHUNK_MULTI_IO);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
}
}
/* Make a copy of the dxpl to test the read operation */
dxpl_read = H5Pcopy(dxpl_write);
VRFY((dxpl_read >= 0), "H5Pcopy succeeded");
/* Write */
ret = H5Dwrite(dataset, data_type, mem_space, file_space, dxpl_write, buffer);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stdout);
VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
/* Retrieve Actual io values */
ret = H5Pget_mpio_actual_io_mode(dxpl_write, &actual_io_mode_write);
VRFY((ret >= 0), "retrieving actual io mode succeeded");
ret = H5Pget_mpio_actual_chunk_opt_mode(dxpl_write, &actual_chunk_opt_mode_write);
VRFY((ret >= 0), "retrieving actual chunk opt mode succeeded");
/* Read */
ret = H5Dread(dataset, data_type, mem_space, file_space, dxpl_read, buffer);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stdout);
VRFY((ret >= 0), "H5Dread() dataset multichunk read succeeded");
/* Retrieve Actual io values */
ret = H5Pget_mpio_actual_io_mode(dxpl_read, &actual_io_mode_read);
VRFY((ret >= 0), "retrieving actual io mode succeeded");
ret = H5Pget_mpio_actual_chunk_opt_mode(dxpl_read, &actual_chunk_opt_mode_read);
VRFY((ret >= 0), "retrieving actual chunk opt mode succeeded");
/* Check write vs read */
VRFY((actual_io_mode_read == actual_io_mode_write),
"reading and writing are the same for actual_io_mode");
VRFY((actual_chunk_opt_mode_read == actual_chunk_opt_mode_write),
"reading and writing are the same for actual_chunk_opt_mode");
/* Test values */
if (actual_chunk_opt_mode_expected != (H5D_mpio_actual_chunk_opt_mode_t)-1 &&
actual_io_mode_expected != (H5D_mpio_actual_io_mode_t)-1) {
HDsnprintf(message, sizeof(message), "Actual Chunk Opt Mode has the correct value for %s.\n",
test_name);
VRFY((actual_chunk_opt_mode_write == actual_chunk_opt_mode_expected), message);
HDsnprintf(message, sizeof(message), "Actual IO Mode has the correct value for %s.\n", test_name);
VRFY((actual_io_mode_write == actual_io_mode_expected), message);
}
else {
HDfprintf(stderr, "%s %d -> (%d,%d)\n", test_name, mpi_rank, actual_chunk_opt_mode_write,
actual_io_mode_write);
}
/* To test that the property is successfully reset to the default, we perform some
* independent I/O after the collective I/O
*/
if (selection_mode == TEST_ACTUAL_IO_RESET) {
if (mpi_rank == 0) {
/* Switch to independent io */
ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_INDEPENDENT);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
ret = H5Pset_dxpl_mpio(dxpl_read, H5FD_MPIO_INDEPENDENT);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* Write */
ret = H5Dwrite(dataset, data_type, H5S_ALL, H5S_ALL, dxpl_write, buffer);
VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
/* Check Properties */
ret = H5Pget_mpio_actual_io_mode(dxpl_write, &actual_io_mode_write);
VRFY((ret >= 0), "retrieving actual io mode succeeded");
ret = H5Pget_mpio_actual_chunk_opt_mode(dxpl_write, &actual_chunk_opt_mode_write);
VRFY((ret >= 0), "retrieving actual chunk opt mode succeeded");
VRFY(actual_chunk_opt_mode_write == H5D_MPIO_NO_CHUNK_OPTIMIZATION,
"actual_chunk_opt_mode has correct value for reset write (independent)");
VRFY(actual_io_mode_write == H5D_MPIO_NO_COLLECTIVE,
"actual_io_mode has correct value for reset write (independent)");
/* Read */
ret = H5Dread(dataset, data_type, H5S_ALL, H5S_ALL, dxpl_read, buffer);
VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
/* Check Properties */
ret = H5Pget_mpio_actual_io_mode(dxpl_read, &actual_io_mode_read);
VRFY((ret >= 0), "retrieving actual io mode succeeded");
ret = H5Pget_mpio_actual_chunk_opt_mode(dxpl_read, &actual_chunk_opt_mode_read);
VRFY((ret >= 0), "retrieving actual chunk opt mode succeeded");
VRFY(actual_chunk_opt_mode_read == H5D_MPIO_NO_CHUNK_OPTIMIZATION,
"actual_chunk_opt_mode has correct value for reset read (independent)");
VRFY(actual_io_mode_read == H5D_MPIO_NO_COLLECTIVE,
"actual_io_mode has correct value for reset read (independent)");
}
}
/* Release some resources */
ret = H5Sclose(sid);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Pclose(dcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Pclose(dxpl_write);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Pclose(dxpl_read);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(mem_space);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Sclose(file_space);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
HDfree(buffer);
return;
}
/* Function: actual_io_mode_tests
*
* Purpose: Tests all possible cases of the actual_io_mode property.
*
* Programmer: Jacob Gruber
* Date: 2011-04-06
*/
void
actual_io_mode_tests(void)
{
int mpi_size = -1;
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Only run these tests if selection I/O is not being used - selection I/O
* bypasses this IO mode decision - it's effectively always multi chunk
* currently */
if (/* !H5_use_selection_io_g */ TRUE) {
test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE);
/*
* Test multi-chunk-io via proc_num threshold
*/
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_IND);
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_COL);
/* The Multi Chunk Mixed test requires at least three processes. */
if (mpi_size > 2)
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX);
else
HDfprintf(stdout, "Multi Chunk Mixed test requires 3 processes minimum\n");
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE);
/*
* Test multi-chunk-io via setting direct property
*/
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND);
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL);
test_actual_io_mode(TEST_ACTUAL_IO_LINK_CHUNK);
test_actual_io_mode(TEST_ACTUAL_IO_CONTIGUOUS);
test_actual_io_mode(TEST_ACTUAL_IO_RESET);
}
return;
}
/*
* Function: test_no_collective_cause_mode
*
* Purpose:
* tests cases for broken collective I/O and checks that the
* H5Pget_mpio_no_collective_cause properties in the DXPL have the correct values.
*
* Input:
* selection_mode: various mode to cause broken collective I/O
* Note: Originally, each TEST case is supposed to be used alone.
* After some discussion, this is updated to take multiple TEST cases
* with '|'. However there is no error check for any of combined
* test cases, so a tester is responsible to understand and feed
* proper combination of TESTs if needed.
*
*
* TEST_COLLECTIVE:
* Test for regular collective I/O without cause of breaking.
* Just to test normal behavior.
*
* TEST_SET_INDEPENDENT:
* Test for Independent I/O as the cause of breaking collective I/O.
*
* TEST_DATATYPE_CONVERSION:
* Test for Data Type Conversion as the cause of breaking collective I/O.
*
* TEST_DATA_TRANSFORMS:
* Test for Data Transform feature as the cause of breaking collective I/O.
*
* TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES:
* Test for NULL dataspace as the cause of breaking collective I/O.
*
* TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT:
* Test for Compact layout as the cause of breaking collective I/O.
*
* TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL:
* Test for Externl-File storage as the cause of breaking collective I/O.
*
* Programmer: Jonathan Kim
* Date: Aug, 2012
*/
#ifdef LATER
#define DSET_NOCOLCAUSE "nocolcause"
#endif
#define FILE_EXTERNAL "nocolcause_extern.data"
static void
test_no_collective_cause_mode(int selection_mode)
{
uint32_t no_collective_cause_local_write = 0;
uint32_t no_collective_cause_local_read = 0;
uint32_t no_collective_cause_local_expected = 0;
uint32_t no_collective_cause_global_write = 0;
uint32_t no_collective_cause_global_read = 0;
uint32_t no_collective_cause_global_expected = 0;
const char *filename;
const char *test_name;
hbool_t is_chunked = 1;
hbool_t is_independent = 0;
int mpi_size = -1;
int mpi_rank = -1;
int length;
int *buffer;
int i;
MPI_Comm mpi_comm;
MPI_Info mpi_info;
hid_t fid = -1;
hid_t sid = -1;
hid_t dataset = -1;
hid_t data_type = H5T_NATIVE_INT;
hid_t fapl = -1;
hid_t dcpl = -1;
hid_t dxpl_write = -1;
hid_t dxpl_read = -1;
hsize_t dims[RANK];
hid_t mem_space = -1;
hid_t file_space = -1;
hsize_t chunk_dims[RANK];
herr_t ret;
/* set to global value as default */
int l_facc_type = facc_type;
char message[256];
/* Set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Barrier(MPI_COMM_WORLD);
HDassert(mpi_size >= 1);
mpi_comm = MPI_COMM_WORLD;
mpi_info = MPI_INFO_NULL;
/* Create the dataset creation plist */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "dataset creation plist created successfully");
if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT) {
ret = H5Pset_layout(dcpl, H5D_COMPACT);
VRFY((ret >= 0), "set COMPACT layout succeeded");
is_chunked = 0;
}
if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL) {
ret = H5Pset_external(dcpl, FILE_EXTERNAL, (off_t)0, H5F_UNLIMITED);
VRFY((ret >= 0), "set EXTERNAL file layout succeeded");
is_chunked = 0;
}
if (selection_mode & TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES) {
sid = H5Screate(H5S_NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
is_chunked = 0;
}
else {
/* Create the basic Space */
/* if this is a compact dataset, create a small dataspace that does not exceed 64K */
if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT) {
dims[0] = ROW_FACTOR * 6;
dims[1] = COL_FACTOR * 6;
}
else {
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
}
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
}
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
HDassert(filename != NULL);
/* Setup the file access template */
fapl = create_faccess_plist(mpi_comm, mpi_info, l_facc_type);
VRFY((fapl >= 0), "create_faccess_plist() succeeded");
/* Create the file */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* If we are not testing contiguous datasets */
if (is_chunked) {
/* Set up chunk information. */
chunk_dims[0] = dims[0] / (hsize_t)mpi_size;
chunk_dims[1] = dims[1];
ret = H5Pset_chunk(dcpl, 2, chunk_dims);
VRFY((ret >= 0), "chunk creation property list succeeded");
}
/* Create the dataset */
dataset = H5Dcreate2(fid, "nocolcause", data_type, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2() dataset succeeded");
/*
* Set expected causes and some tweaks based on the type of test
*/
if (selection_mode & TEST_DATATYPE_CONVERSION) {
test_name = "Broken Collective I/O - Datatype Conversion";
no_collective_cause_local_expected |= H5D_MPIO_DATATYPE_CONVERSION;
no_collective_cause_global_expected |= H5D_MPIO_DATATYPE_CONVERSION;
/* set different sign to trigger type conversion */
data_type = H5T_NATIVE_UINT;
}
if (selection_mode & TEST_DATA_TRANSFORMS) {
test_name = "Broken Collective I/O - DATA Transforms";
no_collective_cause_local_expected |= H5D_MPIO_DATA_TRANSFORMS;
no_collective_cause_global_expected |= H5D_MPIO_DATA_TRANSFORMS;
}
if (selection_mode & TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES) {
test_name = "Broken Collective I/O - No Simple or Scalar DataSpace";
no_collective_cause_local_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES;
no_collective_cause_global_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES;
}
if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT ||
selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL) {
test_name = "Broken Collective I/O - No CONTI or CHUNKED Dataset";
no_collective_cause_local_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
no_collective_cause_global_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
}
if (selection_mode & TEST_COLLECTIVE) {
test_name = "Broken Collective I/O - Not Broken";
no_collective_cause_local_expected = H5D_MPIO_COLLECTIVE;
no_collective_cause_global_expected = H5D_MPIO_COLLECTIVE;
}
if (selection_mode & TEST_SET_INDEPENDENT) {
test_name = "Broken Collective I/O - Independent";
no_collective_cause_local_expected = H5D_MPIO_SET_INDEPENDENT;
no_collective_cause_global_expected = H5D_MPIO_SET_INDEPENDENT;
/* switch to independent io */
is_independent = 1;
}
/* use all spaces for certain tests */
if (selection_mode & TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES ||
selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL) {
file_space = H5S_ALL;
mem_space = H5S_ALL;
}
else {
/* Get the file dataspace */
file_space = H5Dget_space(dataset);
VRFY((file_space >= 0), "H5Dget_space succeeded");
/* Create the memory dataspace */
mem_space = H5Screate_simple(RANK, dims, NULL);
VRFY((mem_space >= 0), "mem_space created");
}
/* Get the number of elements in the selection */
length = (int)(dims[0] * dims[1]);
/* Allocate and initialize the buffer */
buffer = (int *)HDmalloc(sizeof(int) * (size_t)length);
VRFY((buffer != NULL), "HDmalloc of buffer succeeded");
for (i = 0; i < length; i++)
buffer[i] = i;
/* Set up the dxpl for the write */
dxpl_write = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
if (is_independent) {
/* Set Independent I/O */
ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_INDEPENDENT);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
}
else {
/* Set Collective I/O */
ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
}
if (selection_mode & TEST_DATA_TRANSFORMS) {
ret = H5Pset_data_transform(dxpl_write, "x+1");
VRFY((ret >= 0), "H5Pset_data_transform succeeded");
}
/*---------------------
* Test Write access
*---------------------*/
/* Write */
ret = H5Dwrite(dataset, data_type, mem_space, file_space, dxpl_write, buffer);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stdout);
VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
/* Get the cause of broken collective I/O */
ret = H5Pget_mpio_no_collective_cause(dxpl_write, &no_collective_cause_local_write,
&no_collective_cause_global_write);
VRFY((ret >= 0), "retrieving no collective cause succeeded");
/*---------------------
* Test Read access
*---------------------*/
/* Make a copy of the dxpl to test the read operation */
dxpl_read = H5Pcopy(dxpl_write);
VRFY((dxpl_read >= 0), "H5Pcopy succeeded");
/* Read */
ret = H5Dread(dataset, data_type, mem_space, file_space, dxpl_read, buffer);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stdout);
VRFY((ret >= 0), "H5Dread() dataset multichunk read succeeded");
/* Get the cause of broken collective I/O */
ret = H5Pget_mpio_no_collective_cause(dxpl_read, &no_collective_cause_local_read,
&no_collective_cause_global_read);
VRFY((ret >= 0), "retrieving no collective cause succeeded");
/* Check write vs read */
VRFY((no_collective_cause_local_read == no_collective_cause_local_write),
"reading and writing are the same for local cause of Broken Collective I/O");
VRFY((no_collective_cause_global_read == no_collective_cause_global_write),
"reading and writing are the same for global cause of Broken Collective I/O");
/* Test values */
HDmemset(message, 0, sizeof(message));
HDsnprintf(message, sizeof(message),
"Local cause of Broken Collective I/O has the correct value for %s.\n", test_name);
VRFY((no_collective_cause_local_write == no_collective_cause_local_expected), message);
HDmemset(message, 0, sizeof(message));
HDsnprintf(message, sizeof(message),
"Global cause of Broken Collective I/O has the correct value for %s.\n", test_name);
VRFY((no_collective_cause_global_write == no_collective_cause_global_expected), message);
/* Release some resources */
if (sid)
H5Sclose(sid);
if (dcpl)
H5Pclose(dcpl);
if (dxpl_write)
H5Pclose(dxpl_write);
if (dxpl_read)
H5Pclose(dxpl_read);
if (dataset)
H5Dclose(dataset);
if (mem_space)
H5Sclose(mem_space);
if (file_space)
H5Sclose(file_space);
if (fid)
H5Fclose(fid);
HDfree(buffer);
/* clean up external file */
if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL)
H5Fdelete(FILE_EXTERNAL, fapl);
if (fapl)
H5Pclose(fapl);
return;
}
/* Function: no_collective_cause_tests
*
* Purpose: Tests cases for broken collective IO.
*
* Programmer: Jonathan Kim
* Date: Aug, 2012
*/
void
no_collective_cause_tests(void)
{
/*
* Test individual cause
*/
test_no_collective_cause_mode(TEST_COLLECTIVE);
test_no_collective_cause_mode(TEST_SET_INDEPENDENT);
test_no_collective_cause_mode(TEST_DATATYPE_CONVERSION);
test_no_collective_cause_mode(TEST_DATA_TRANSFORMS);
test_no_collective_cause_mode(TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES);
test_no_collective_cause_mode(TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT);
test_no_collective_cause_mode(TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL);
/*
* Test combined causes
*/
test_no_collective_cause_mode(TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL | TEST_DATATYPE_CONVERSION);
test_no_collective_cause_mode(TEST_DATATYPE_CONVERSION | TEST_DATA_TRANSFORMS);
test_no_collective_cause_mode(TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL | TEST_DATATYPE_CONVERSION |
TEST_DATA_TRANSFORMS);
return;
}
/*
* Test consistency semantics of atomic mode
*/
/*
* Example of using the parallel HDF5 library to create a dataset,
* where process 0 writes and the other processes read at the same
* time. If atomic mode is set correctly, the other processes should
* read the old values in the dataset or the new ones.
*/
void
dataset_atomicity(void)
{
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t sid; /* Dataspace ID */
hid_t dataset1; /* Dataset IDs */
hsize_t dims[RANK]; /* dataset dim sizes */
int *write_buf = NULL; /* data buffer */
int *read_buf = NULL; /* data buffer */
int buf_size;
hid_t dataset2;
hid_t file_dataspace; /* File dataspace ID */
hid_t mem_dataspace; /* Memory dataspace ID */
hsize_t start[RANK];
hsize_t stride[RANK];
hsize_t count[RANK];
hsize_t block[RANK];
const char *filename;
herr_t ret; /* Generic return value */
int mpi_size, mpi_rank;
int i, j, k;
hbool_t atomicity = FALSE;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
dim0 = 64;
dim1 = 32;
filename = PARATESTFILE /* GetTestParameters() */;
if (facc_type != FACC_MPIO) {
HDprintf("Atomicity tests will not work without the MPIO VFD\n");
return;
}
if (VERBOSE_MED)
HDprintf("atomic writes to file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, basic dataset, or more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
buf_size = dim0 * dim1;
/* allocate memory for data buffer */
write_buf = (int *)HDcalloc((size_t)buf_size, sizeof(int));
VRFY((write_buf != NULL), "write_buf HDcalloc succeeded");
/* allocate memory for data buffer */
read_buf = (int *)HDcalloc((size_t)buf_size, sizeof(int));
VRFY((read_buf != NULL), "read_buf HDcalloc succeeded");
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* setup dimensionality object */
dims[0] = (hsize_t)dim0;
dims[1] = (hsize_t)dim1;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* create datasets */
dataset1 = H5Dcreate2(fid, DATASETNAME5, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dcreate2 succeeded");
dataset2 = H5Dcreate2(fid, DATASETNAME6, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dcreate2 succeeded");
/* initialize datasets to 0s */
if (0 == mpi_rank) {
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf);
VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf);
VRFY((ret >= 0), "H5Dwrite dataset2 succeeded");
}
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(sid);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
MPI_Barrier(comm);
/* make sure setting atomicity fails on a serial file ID */
/* file locking allows only one file open (serial) for writing */
if (MAINPROCESS) {
fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
VRFY((fid >= 0), "H5Fopen succeeded");
/* should fail */
H5E_BEGIN_TRY
{
ret = H5Fset_mpi_atomicity(fid, TRUE);
}
H5E_END_TRY
VRFY((ret == FAIL), "H5Fset_mpi_atomicity failed");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
MPI_Barrier(comm);
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* open the file collectively */
fid = H5Fopen(filename, H5F_ACC_RDWR, acc_tpl);
VRFY((fid >= 0), "H5Fopen succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Fset_mpi_atomicity(fid, TRUE);
VRFY((ret >= 0), "H5Fset_mpi_atomicity succeeded");
/* open dataset1 (contiguous case) */
dataset1 = H5Dopen2(fid, DATASETNAME5, H5P_DEFAULT);
VRFY((dataset1 >= 0), "H5Dopen2 succeeded");
if (0 == mpi_rank) {
for (i = 0; i < buf_size; i++) {
write_buf[i] = 5;
}
}
else {
for (i = 0; i < buf_size; i++) {
read_buf[i] = 8;
}
}
/* check that the atomicity flag is set */
ret = H5Fget_mpi_atomicity(fid, &atomicity);
VRFY((ret >= 0), "atomcity get failed");
VRFY((atomicity == TRUE), "atomcity set failed");
MPI_Barrier(comm);
/* Process 0 writes contiguously to the entire dataset */
if (0 == mpi_rank) {
ret = H5Dwrite(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf);
VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
}
/* The other processes read the entire dataset */
else {
ret = H5Dread(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf);
VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
}
if (VERBOSE_MED) {
i = 0;
j = 0;
k = 0;
for (i = 0; i < dim0; i++) {
HDprintf("\n");
for (j = 0; j < dim1; j++)
HDprintf("%d ", read_buf[k++]);
}
}
/* The processes that read the dataset must either read all values
as 0 (read happened before process 0 wrote to dataset 1), or 5
(read happened after process 0 wrote to dataset 1) */
if (0 != mpi_rank) {
int compare = read_buf[0];
VRFY((compare == 0 || compare == 5),
"Atomicity Test Failed Process %d: Value read should be 0 or 5\n");
for (i = 1; i < buf_size; i++) {
if (read_buf[i] != compare) {
HDprintf("Atomicity Test Failed Process %d: read_buf[%d] is %d, should be %d\n", mpi_rank, i,
read_buf[i], compare);
nerrors++;
}
}
}
ret = H5Dclose(dataset1);
VRFY((ret >= 0), "H5D close succeeded");
/* release data buffers */
if (write_buf)
HDfree(write_buf);
if (read_buf)
HDfree(read_buf);
/* open dataset2 (non-contiguous case) */
dataset2 = H5Dopen2(fid, DATASETNAME6, H5P_DEFAULT);
VRFY((dataset2 >= 0), "H5Dopen2 succeeded");
/* allocate memory for data buffer */
write_buf = (int *)HDcalloc((size_t)buf_size, sizeof(int));
VRFY((write_buf != NULL), "write_buf HDcalloc succeeded");
/* allocate memory for data buffer */
read_buf = (int *)HDcalloc((size_t)buf_size, sizeof(int));
VRFY((read_buf != NULL), "read_buf HDcalloc succeeded");
for (i = 0; i < buf_size; i++) {
write_buf[i] = 5;
}
for (i = 0; i < buf_size; i++) {
read_buf[i] = 8;
}
atomicity = FALSE;
/* check that the atomicity flag is set */
ret = H5Fget_mpi_atomicity(fid, &atomicity);
VRFY((ret >= 0), "atomcity get failed");
VRFY((atomicity == TRUE), "atomcity set failed");
block[0] = (hsize_t)(dim0 / mpi_size - 1);
block[1] = (hsize_t)(dim1 / mpi_size - 1);
stride[0] = block[0] + 1;
stride[1] = block[1] + 1;
count[0] = (hsize_t)mpi_size;
count[1] = (hsize_t)mpi_size;
start[0] = 0;
start[1] = 0;
/* create a file dataspace */
file_dataspace = H5Dget_space(dataset2);
VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace */
mem_dataspace = H5Screate_simple(RANK, dims, NULL);
VRFY((mem_dataspace >= 0), "");
ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
MPI_Barrier(comm);
/* Process 0 writes to the dataset */
if (0 == mpi_rank) {
ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, write_buf);
VRFY((ret >= 0), "H5Dwrite dataset2 succeeded");
}
/* All processes wait for the write to finish. This works because
atomicity is set to true */
MPI_Barrier(comm);
/* The other processes read the entire dataset */
if (0 != mpi_rank) {
ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, H5P_DEFAULT, read_buf);
VRFY((ret >= 0), "H5Dread dataset2 succeeded");
}
if (VERBOSE_MED) {
if (mpi_rank == 1) {
i = 0;
j = 0;
k = 0;
for (i = 0; i < dim0; i++) {
HDprintf("\n");
for (j = 0; j < dim1; j++)
HDprintf("%d ", read_buf[k++]);
}
HDprintf("\n");
}
}
/* The processes that read the dataset must either read all values
as 5 (read happened after process 0 wrote to dataset 1) */
if (0 != mpi_rank) {
int compare;
i = 0;
j = 0;
k = 0;
compare = 5;
for (i = 0; i < dim0; i++) {
if (i >= mpi_rank * ((int)block[0] + 1)) {
break;
}
if ((i + 1) % ((int)block[0] + 1) == 0) {
k += dim1;
continue;
}
for (j = 0; j < dim1; j++) {
if (j >= mpi_rank * ((int)block[1] + 1)) {
k += dim1 - mpi_rank * ((int)block[1] + 1);
break;
}
if ((j + 1) % ((int)block[1] + 1) == 0) {
k++;
continue;
}
else if (compare != read_buf[k]) {
HDprintf("Atomicity Test Failed Process %d: read_buf[%d] is %d, should be %d\n", mpi_rank,
k, read_buf[k], compare);
nerrors++;
}
k++;
}
}
}
ret = H5Dclose(dataset2);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(file_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Sclose(mem_dataspace);
VRFY((ret >= 0), "H5Sclose succeeded");
/* release data buffers */
if (write_buf)
HDfree(write_buf);
if (read_buf)
HDfree(read_buf);
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
/* Function: dense_attr_test
*
* Purpose: Test cases for writing dense attributes in parallel
*
* Programmer: Quincey Koziol
* Date: April, 2013
*/
void
test_dense_attr(void)
{
int mpi_size, mpi_rank;
hid_t fpid, fid;
hid_t gid, gpid;
hid_t atFileSpace, atid;
hsize_t atDims[1] = {10000};
herr_t status;
const char *filename;
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, group, dataset, or attribute aren't supported with "
"this connector\n");
fflush(stdout);
}
return;
}
/* get filename */
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
HDassert(filename != NULL);
fpid = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fpid > 0), "H5Pcreate succeeded");
status = H5Pset_libver_bounds(fpid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
VRFY((status >= 0), "H5Pset_libver_bounds succeeded");
status = H5Pset_fapl_mpio(fpid, MPI_COMM_WORLD, MPI_INFO_NULL);
VRFY((status >= 0), "H5Pset_fapl_mpio succeeded");
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fpid);
VRFY((fid > 0), "H5Fcreate succeeded");
status = H5Pclose(fpid);
VRFY((status >= 0), "H5Pclose succeeded");
gpid = H5Pcreate(H5P_GROUP_CREATE);
VRFY((gpid > 0), "H5Pcreate succeeded");
status = H5Pset_attr_phase_change(gpid, 0, 0);
VRFY((status >= 0), "H5Pset_attr_phase_change succeeded");
gid = H5Gcreate2(fid, "foo", H5P_DEFAULT, gpid, H5P_DEFAULT);
VRFY((gid > 0), "H5Gcreate2 succeeded");
status = H5Pclose(gpid);
VRFY((status >= 0), "H5Pclose succeeded");
atFileSpace = H5Screate_simple(1, atDims, NULL);
VRFY((atFileSpace > 0), "H5Screate_simple succeeded");
atid = H5Acreate2(gid, "bar", H5T_STD_U64LE, atFileSpace, H5P_DEFAULT, H5P_DEFAULT);
VRFY((atid > 0), "H5Acreate succeeded");
status = H5Sclose(atFileSpace);
VRFY((status >= 0), "H5Sclose succeeded");
status = H5Aclose(atid);
VRFY((status >= 0), "H5Aclose succeeded");
status = H5Gclose(gid);
VRFY((status >= 0), "H5Gclose succeeded");
status = H5Fclose(fid);
VRFY((status >= 0), "H5Fclose succeeded");
return;
}
+1032
View File
@@ -0,0 +1,1032 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Parallel tests for file operations
*/
#include "hdf5.h"
#include "testphdf5.h"
#if 0
#include "H5CXprivate.h" /* API Contexts */
#include "H5Iprivate.h"
#include "H5PBprivate.h"
/*
* This file needs to access private information from the H5F package.
*/
#define H5AC_FRIEND /*suppress error about including H5ACpkg */
#include "H5ACpkg.h"
#define H5C_FRIEND /*suppress error about including H5Cpkg */
#include "H5Cpkg.h"
#define H5F_FRIEND /*suppress error about including H5Fpkg */
#define H5F_TESTING
#include "H5Fpkg.h"
#define H5MF_FRIEND /*suppress error about including H5MFpkg */
#include "H5MFpkg.h"
#endif
#define NUM_DSETS 5
int mpi_size, mpi_rank;
#if 0
static int create_file(const char *filename, hid_t fcpl, hid_t fapl, int metadata_write_strategy);
static int open_file(const char *filename, hid_t fapl, int metadata_write_strategy, hsize_t page_size,
size_t page_buffer_size);
#endif
/*
* test file access by communicator besides COMM_WORLD.
* Split COMM_WORLD into two, one (even_comm) contains the original
* processes of even ranks. The other (odd_comm) contains the original
* processes of odd ranks. Processes in even_comm creates a file, then
* cloose it, using even_comm. Processes in old_comm just do a barrier
* using odd_comm. Then they all do a barrier using COMM_WORLD.
* If the file creation and cloose does not do correct collective action
* according to the communicator argument, the processes will freeze up
* sooner or later due to barrier mixed up.
*/
void
test_split_comm_access(void)
{
MPI_Comm comm;
MPI_Info info = MPI_INFO_NULL;
int is_old, mrc;
int newrank, newprocs;
hid_t fid; /* file IDs */
hid_t acc_tpl; /* File access properties */
herr_t ret; /* generic return value */
const char *filename;
filename = (const char *)PARATESTFILE /* GetTestParameters()*/;
if (VERBOSE_MED)
HDprintf("Split Communicator access test on file %s\n", filename);
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file aren't supported with this connector\n");
fflush(stdout);
}
return;
}
is_old = mpi_rank % 2;
mrc = MPI_Comm_split(MPI_COMM_WORLD, is_old, mpi_rank, &comm);
VRFY((mrc == MPI_SUCCESS), "");
MPI_Comm_size(comm, &newprocs);
MPI_Comm_rank(comm, &newrank);
if (is_old) {
/* odd-rank processes */
mrc = MPI_Barrier(comm);
VRFY((mrc == MPI_SUCCESS), "");
}
else {
/* even-rank processes */
int sub_mpi_rank; /* rank in the sub-comm */
MPI_Comm_rank(comm, &sub_mpi_rank);
/* setup file access template */
acc_tpl = create_faccess_plist(comm, info, facc_type);
VRFY((acc_tpl >= 0), "");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
/* close the file */
ret = H5Fclose(fid);
VRFY((ret >= 0), "");
/* delete the test file */
ret = H5Fdelete(filename, acc_tpl);
VRFY((ret >= 0), "H5Fdelete succeeded");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "");
}
mrc = MPI_Comm_free(&comm);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free succeeded");
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "final MPI_Barrier succeeded");
}
#if 0
void
test_page_buffer_access(void)
{
hid_t file_id = -1; /* File ID */
hid_t fcpl, fapl;
size_t page_count = 0;
int i, num_elements = 200;
haddr_t raw_addr, meta_addr;
int *data;
H5F_t *f = NULL;
herr_t ret; /* generic return value */
const char *filename;
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
filename = (const char *)GetTestParameters();
if (VERBOSE_MED)
HDprintf("Page Buffer Usage in Parallel %s\n", filename);
fapl = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl >= 0), "create_faccess_plist succeeded");
fcpl = H5Pcreate(H5P_FILE_CREATE);
VRFY((fcpl >= 0), "");
ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 1, (hsize_t)0);
VRFY((ret == 0), "");
ret = H5Pset_file_space_page_size(fcpl, sizeof(int) * 128);
VRFY((ret == 0), "");
ret = H5Pset_page_buffer_size(fapl, sizeof(int) * 100000, 0, 0);
VRFY((ret == 0), "");
/* This should fail because collective metadata writes are not supported with page buffering */
H5E_BEGIN_TRY
{
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
}
H5E_END_TRY;
VRFY((file_id < 0), "H5Fcreate failed");
/* disable collective metadata writes for page buffering to work */
ret = H5Pset_coll_metadata_write(fapl, FALSE);
VRFY((ret >= 0), "");
ret = create_file(filename, fcpl, fapl, H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED);
VRFY((ret == 0), "");
ret = open_file(filename, fapl, H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED, sizeof(int) * 100,
sizeof(int) * 100000);
VRFY((ret == 0), "");
ret = create_file(filename, fcpl, fapl, H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY);
VRFY((ret == 0), "");
ret = open_file(filename, fapl, H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY, sizeof(int) * 100,
sizeof(int) * 100000);
VRFY((ret == 0), "");
ret = H5Pset_file_space_page_size(fcpl, sizeof(int) * 100);
VRFY((ret == 0), "");
data = (int *)HDmalloc(sizeof(int) * (size_t)num_elements);
/* initialize all the elements to have a value of -1 */
for (i = 0; i < num_elements; i++)
data[i] = -1;
if (MAINPROCESS) {
hid_t fapl_self = H5I_INVALID_HID;
fapl_self = create_faccess_plist(MPI_COMM_SELF, MPI_INFO_NULL, facc_type);
ret = H5Pset_page_buffer_size(fapl_self, sizeof(int) * 1000, 0, 0);
VRFY((ret == 0), "");
/* collective metadata writes do not work with page buffering */
ret = H5Pset_coll_metadata_write(fapl_self, FALSE);
VRFY((ret >= 0), "");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_self);
VRFY((file_id >= 0), "");
/* Push API context */
ret = H5CX_push();
VRFY((ret == 0), "H5CX_push()");
api_ctx_pushed = TRUE;
/* Get a pointer to the internal file object */
f = (H5F_t *)H5I_object(file_id);
VRFY((f->shared->page_buf != NULL), "Page Buffer created with 1 process");
/* allocate space for 200 raw elements */
raw_addr = H5MF_alloc(f, H5FD_MEM_DRAW, sizeof(int) * (size_t)num_elements);
VRFY((raw_addr != HADDR_UNDEF), "");
/* allocate space for 200 metadata elements */
meta_addr = H5MF_alloc(f, H5FD_MEM_SUPER, sizeof(int) * (size_t)num_elements);
VRFY((meta_addr != HADDR_UNDEF), "");
page_count = 0;
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * (size_t)num_elements, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * (size_t)num_elements, data);
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * (size_t)num_elements, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update the first 50 elements */
for (i = 0; i < 50; i++)
data[i] = i;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
page_count += 2;
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update the second 50 elements */
for (i = 0; i < 50; i++)
data[i] = i + 50;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr + (sizeof(int) * 50), sizeof(int) * 50, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr + (sizeof(int) * 50), sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update 100 - 200 */
for (i = 0; i < 100; i++)
data[i] = i + 100;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr + (sizeof(int) * 100), sizeof(int) * 100, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr + (sizeof(int) * 100), sizeof(int) * 100, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
ret = H5PB_flush(f->shared);
VRFY((ret == 0), "");
/* read elements 0 - 200 */
ret = H5F_block_read(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 200, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 200; i++)
VRFY((data[i] == i), "Read different values than written");
ret = H5F_block_read(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 200, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 200; i++)
VRFY((data[i] == i), "Read different values than written");
/* read elements 0 - 50 */
ret = H5F_block_read(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == i), "Read different values than written");
ret = H5F_block_read(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == i), "Read different values than written");
/* close the file */
ret = H5Fclose(file_id);
VRFY((ret >= 0), "H5Fclose succeeded");
ret = H5Pclose(fapl_self);
VRFY((ret >= 0), "H5Pclose succeeded");
/* Pop API context */
if (api_ctx_pushed) {
ret = H5CX_pop(FALSE);
VRFY((ret == 0), "H5CX_pop()");
api_ctx_pushed = FALSE;
}
}
MPI_Barrier(MPI_COMM_WORLD);
if (mpi_size > 1) {
ret = H5Pset_page_buffer_size(fapl, sizeof(int) * 1000, 0, 0);
VRFY((ret == 0), "");
/* collective metadata writes do not work with page buffering */
ret = H5Pset_coll_metadata_write(fapl, FALSE);
VRFY((ret >= 0), "");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
VRFY((file_id >= 0), "");
/* Push API context */
ret = H5CX_push();
VRFY((ret == 0), "H5CX_push()");
api_ctx_pushed = TRUE;
/* Get a pointer to the internal file object */
f = (H5F_t *)H5I_object(file_id);
VRFY((f->shared->page_buf != NULL), "Page Buffer created with 1 process");
/* allocate space for 200 raw elements */
raw_addr = H5MF_alloc(f, H5FD_MEM_DRAW, sizeof(int) * (size_t)num_elements);
VRFY((raw_addr != HADDR_UNDEF), "");
/* allocate space for 200 metadata elements */
meta_addr = H5MF_alloc(f, H5FD_MEM_SUPER, sizeof(int) * (size_t)num_elements);
VRFY((meta_addr != HADDR_UNDEF), "");
page_count = 0;
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * (size_t)num_elements, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * (size_t)num_elements, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update the first 50 elements */
for (i = 0; i < 50; i++)
data[i] = i;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update the second 50 elements */
for (i = 0; i < 50; i++)
data[i] = i + 50;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr + (sizeof(int) * 50), sizeof(int) * 50, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr + (sizeof(int) * 50), sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* update 100 - 200 */
for (i = 0; i < 100; i++)
data[i] = i + 100;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr + (sizeof(int) * 100), sizeof(int) * 100, data);
VRFY((ret == 0), "");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr + (sizeof(int) * 100), sizeof(int) * 100, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
ret = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((ret == 0), "");
/* read elements 0 - 200 */
ret = H5F_block_read(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 200, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 200; i++)
VRFY((data[i] == i), "Read different values than written");
ret = H5F_block_read(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 200, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 200; i++)
VRFY((data[i] == i), "Read different values than written");
/* read elements 0 - 50 */
ret = H5F_block_read(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == i), "Read different values than written");
ret = H5F_block_read(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
page_count += 1;
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == i), "Read different values than written");
MPI_Barrier(MPI_COMM_WORLD);
/* reset the first 50 elements to -1*/
for (i = 0; i < 50; i++)
data[i] = -1;
ret = H5F_block_write(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
ret = H5F_block_write(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
/* read elements 0 - 50 */
ret = H5F_block_read(f, H5FD_MEM_DRAW, raw_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == -1), "Read different values than written");
ret = H5F_block_read(f, H5FD_MEM_SUPER, meta_addr, sizeof(int) * 50, data);
VRFY((ret == 0), "");
VRFY((H5SL_count(f->shared->page_buf->slist_ptr) == page_count), "Wrong number of pages in PB");
for (i = 0; i < 50; i++)
VRFY((data[i] == -1), "Read different values than written");
/* close the file */
ret = H5Fclose(file_id);
VRFY((ret >= 0), "H5Fclose succeeded");
}
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Pclose(fcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* Pop API context */
if (api_ctx_pushed) {
ret = H5CX_pop(FALSE);
VRFY((ret == 0), "H5CX_pop()");
api_ctx_pushed = FALSE;
}
HDfree(data);
data = NULL;
MPI_Barrier(MPI_COMM_WORLD);
}
static int
create_file(const char *filename, hid_t fcpl, hid_t fapl, int metadata_write_strategy)
{
hid_t file_id, dset_id, grp_id;
hid_t sid, mem_dataspace;
hsize_t start[RANK];
hsize_t count[RANK];
hsize_t stride[RANK];
hsize_t block[RANK];
DATATYPE *data_array = NULL;
hsize_t dims[RANK], i;
hsize_t num_elements;
int k;
char dset_name[20];
H5F_t *f = NULL;
H5C_t *cache_ptr = NULL;
H5AC_cache_config_t config;
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
herr_t ret;
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
VRFY((file_id >= 0), "");
ret = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((ret == 0), "");
/* Push API context */
ret = H5CX_push();
VRFY((ret == 0), "H5CX_push()");
api_ctx_pushed = TRUE;
f = (H5F_t *)H5I_object(file_id);
VRFY((f != NULL), "");
cache_ptr = f->shared->cache;
VRFY((cache_ptr->magic == H5C__H5C_T_MAGIC), "");
cache_ptr->ignore_tags = TRUE;
H5C_stats__reset(cache_ptr);
config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
ret = H5AC_get_cache_auto_resize_config(cache_ptr, &config);
VRFY((ret == 0), "");
config.metadata_write_strategy = metadata_write_strategy;
ret = H5AC_set_cache_auto_resize_config(cache_ptr, &config);
VRFY((ret == 0), "");
grp_id = H5Gcreate2(file_id, "GROUP", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((grp_id >= 0), "");
dims[0] = (hsize_t)(ROW_FACTOR * mpi_size);
dims[1] = (hsize_t)(COL_FACTOR * mpi_size);
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
/* Each process takes a slabs of rows. */
block[0] = dims[0] / (hsize_t)mpi_size;
block[1] = dims[1];
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank * block[0];
start[1] = 0;
num_elements = block[0] * block[1];
/* allocate memory for data buffer */
data_array = (DATATYPE *)HDmalloc(num_elements * sizeof(DATATYPE));
VRFY((data_array != NULL), "data_array HDmalloc succeeded");
/* put some trivial data in the data_array */
for (i = 0; i < num_elements; i++)
data_array[i] = mpi_rank + 1;
ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(1, &num_elements, NULL);
VRFY((mem_dataspace >= 0), "");
for (k = 0; k < NUM_DSETS; k++) {
HDsnprintf(dset_name, sizeof(dset_name), "D1dset%d", k);
dset_id = H5Dcreate2(grp_id, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
ret = H5Dclose(dset_id);
VRFY((ret == 0), "");
HDsnprintf(dset_name, sizeof(dset_name), "D2dset%d", k);
dset_id = H5Dcreate2(grp_id, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
ret = H5Dclose(dset_id);
VRFY((ret == 0), "");
HDsnprintf(dset_name, sizeof(dset_name), "D3dset%d", k);
dset_id = H5Dcreate2(grp_id, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
ret = H5Dclose(dset_id);
VRFY((ret == 0), "");
HDsnprintf(dset_name, sizeof(dset_name), "dset%d", k);
dset_id = H5Dcreate2(grp_id, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
ret = H5Dwrite(dset_id, H5T_NATIVE_INT, mem_dataspace, sid, H5P_DEFAULT, data_array);
VRFY((ret == 0), "");
ret = H5Dclose(dset_id);
VRFY((ret == 0), "");
HDmemset(data_array, 0, num_elements * sizeof(DATATYPE));
dset_id = H5Dopen2(grp_id, dset_name, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
ret = H5Dread(dset_id, H5T_NATIVE_INT, mem_dataspace, sid, H5P_DEFAULT, data_array);
VRFY((ret == 0), "");
ret = H5Dclose(dset_id);
VRFY((ret == 0), "");
for (i = 0; i < num_elements; i++)
VRFY((data_array[i] == mpi_rank + 1), "Dataset Verify failed");
HDsnprintf(dset_name, sizeof(dset_name), "D1dset%d", k);
ret = H5Ldelete(grp_id, dset_name, H5P_DEFAULT);
VRFY((ret == 0), "");
HDsnprintf(dset_name, sizeof(dset_name), "D2dset%d", k);
ret = H5Ldelete(grp_id, dset_name, H5P_DEFAULT);
VRFY((ret == 0), "");
HDsnprintf(dset_name, sizeof(dset_name), "D3dset%d", k);
ret = H5Ldelete(grp_id, dset_name, H5P_DEFAULT);
VRFY((ret == 0), "");
}
ret = H5Gclose(grp_id);
VRFY((ret == 0), "");
ret = H5Fclose(file_id);
VRFY((ret == 0), "");
ret = H5Sclose(sid);
VRFY((ret == 0), "");
ret = H5Sclose(mem_dataspace);
VRFY((ret == 0), "");
/* Pop API context */
if (api_ctx_pushed) {
ret = H5CX_pop(FALSE);
VRFY((ret == 0), "H5CX_pop()");
api_ctx_pushed = FALSE;
}
MPI_Barrier(MPI_COMM_WORLD);
HDfree(data_array);
return 0;
} /* create_file */
static int
open_file(const char *filename, hid_t fapl, int metadata_write_strategy, hsize_t page_size,
size_t page_buffer_size)
{
hid_t file_id, dset_id, grp_id, grp_id2;
hid_t sid, mem_dataspace;
DATATYPE *data_array = NULL;
hsize_t dims[RANK];
hsize_t start[RANK];
hsize_t count[RANK];
hsize_t stride[RANK];
hsize_t block[RANK];
int i, k, ndims;
hsize_t num_elements;
char dset_name[20];
H5F_t *f = NULL;
H5C_t *cache_ptr = NULL;
H5AC_cache_config_t config;
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
herr_t ret;
config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
ret = H5Pget_mdc_config(fapl, &config);
VRFY((ret == 0), "");
config.metadata_write_strategy = metadata_write_strategy;
ret = H5Pget_mdc_config(fapl, &config);
VRFY((ret == 0), "");
file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl);
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((file_id >= 0), "");
/* Push API context */
ret = H5CX_push();
VRFY((ret == 0), "H5CX_push()");
api_ctx_pushed = TRUE;
ret = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((ret == 0), "");
f = (H5F_t *)H5I_object(file_id);
VRFY((f != NULL), "");
cache_ptr = f->shared->cache;
VRFY((cache_ptr->magic == H5C__H5C_T_MAGIC), "");
MPI_Barrier(MPI_COMM_WORLD);
VRFY((f->shared->page_buf != NULL), "");
VRFY((f->shared->page_buf->page_size == page_size), "");
VRFY((f->shared->page_buf->max_size == page_buffer_size), "");
grp_id = H5Gopen2(file_id, "GROUP", H5P_DEFAULT);
VRFY((grp_id >= 0), "");
dims[0] = (hsize_t)(ROW_FACTOR * mpi_size);
dims[1] = (hsize_t)(COL_FACTOR * mpi_size);
/* Each process takes a slabs of rows. */
block[0] = dims[0] / (hsize_t)mpi_size;
block[1] = dims[1];
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank * block[0];
start[1] = 0;
num_elements = block[0] * block[1];
/* allocate memory for data buffer */
data_array = (DATATYPE *)HDmalloc(num_elements * sizeof(DATATYPE));
VRFY((data_array != NULL), "data_array HDmalloc succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(1, &num_elements, NULL);
VRFY((mem_dataspace >= 0), "");
for (k = 0; k < NUM_DSETS; k++) {
HDsnprintf(dset_name, sizeof(dset_name), "dset%d", k);
dset_id = H5Dopen2(grp_id, dset_name, H5P_DEFAULT);
VRFY((dset_id >= 0), "");
sid = H5Dget_space(dset_id);
VRFY((dset_id >= 0), "H5Dget_space succeeded");
ndims = H5Sget_simple_extent_dims(sid, dims, NULL);
VRFY((ndims == 2), "H5Sget_simple_extent_dims succeeded");
VRFY(dims[0] == (hsize_t)(ROW_FACTOR * mpi_size), "Wrong dataset dimensions");
VRFY(dims[1] == (hsize_t)(COL_FACTOR * mpi_size), "Wrong dataset dimensions");
ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
ret = H5Dread(dset_id, H5T_NATIVE_INT, mem_dataspace, sid, H5P_DEFAULT, data_array);
VRFY((ret >= 0), "");
ret = H5Dclose(dset_id);
VRFY((ret >= 0), "");
ret = H5Sclose(sid);
VRFY((ret == 0), "");
for (i = 0; i < (int)num_elements; i++)
VRFY((data_array[i] == mpi_rank + 1), "Dataset Verify failed");
}
grp_id2 = H5Gcreate2(file_id, "GROUP/GROUP2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((grp_id2 >= 0), "");
ret = H5Gclose(grp_id2);
VRFY((ret == 0), "");
ret = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((ret == 0), "");
MPI_Barrier(MPI_COMM_WORLD);
/* flush invalidate each ring, starting from the outermost ring and
* working inward.
*/
for (i = 0; i < H5C__HASH_TABLE_LEN; i++) {
H5C_cache_entry_t *entry_ptr = NULL;
entry_ptr = cache_ptr->index[i];
while (entry_ptr != NULL) {
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(entry_ptr->is_dirty == FALSE);
if (!entry_ptr->is_pinned && !entry_ptr->is_protected) {
ret = H5AC_expunge_entry(f, entry_ptr->type, entry_ptr->addr, 0);
VRFY((ret == 0), "");
}
entry_ptr = entry_ptr->ht_next;
}
}
MPI_Barrier(MPI_COMM_WORLD);
grp_id2 = H5Gopen2(file_id, "GROUP/GROUP2", H5P_DEFAULT);
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((grp_id2 >= 0), "");
ret = H5Gclose(grp_id2);
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((ret == 0), "");
ret = H5Gclose(grp_id);
VRFY((ret == 0), "");
ret = H5Fclose(file_id);
VRFY((ret == 0), "");
ret = H5Sclose(mem_dataspace);
VRFY((ret == 0), "");
/* Pop API context */
if (api_ctx_pushed) {
ret = H5CX_pop(FALSE);
VRFY((ret == 0), "H5CX_pop()");
api_ctx_pushed = FALSE;
}
HDfree(data_array);
return nerrors;
}
#endif
/*
* NOTE: See HDFFV-10894 and add tests later to verify MPI-specific properties in the
* incoming fapl that could conflict with the existing values in H5F_shared_t on
* multiple opens of the same file.
*/
void
test_file_properties(void)
{
hid_t fid = H5I_INVALID_HID; /* HDF5 file ID */
hid_t fapl_id = H5I_INVALID_HID; /* File access plist */
hid_t fapl_copy_id = H5I_INVALID_HID; /* File access plist */
hbool_t is_coll;
htri_t are_equal;
const char *filename;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
MPI_Comm comm_out = MPI_COMM_NULL;
MPI_Info info_out = MPI_INFO_NULL;
herr_t ret; /* Generic return value */
int mpi_ret; /* MPI return value */
int cmp; /* Compare value */
/* set up MPI parameters */
mpi_ret = MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
VRFY((mpi_ret >= 0), "MPI_Comm_size succeeded");
mpi_ret = MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
VRFY((mpi_ret >= 0), "MPI_Comm_rank succeeded");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file aren't supported with this connector\n");
fflush(stdout);
}
return;
}
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
mpi_ret = MPI_Info_create(&info);
VRFY((mpi_ret >= 0), "MPI_Info_create succeeded");
mpi_ret = MPI_Info_set(info, "hdf_info_prop1", "xyz");
VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_set");
/* setup file access plist */
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id != H5I_INVALID_HID), "H5Pcreate");
ret = H5Pset_fapl_mpio(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_fapl_mpio");
/* Check getting and setting MPI properties
* (for use in VOL connectors, not the MPI-I/O VFD)
*/
ret = H5Pset_mpi_params(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_mpi_params succeeded");
ret = H5Pget_mpi_params(fapl_id, &comm_out, &info_out);
VRFY((ret >= 0), "H5Pget_mpi_params succeeded");
/* Check the communicator */
VRFY((comm != comm_out), "Communicators should not be bitwise identical");
cmp = MPI_UNEQUAL;
mpi_ret = MPI_Comm_compare(comm, comm_out, &cmp);
VRFY((ret >= 0), "MPI_Comm_compare succeeded");
VRFY((cmp == MPI_CONGRUENT), "Communicators should be congruent via MPI_Comm_compare");
/* Check the info object */
VRFY((info != info_out), "Info objects should not be bitwise identical");
/* Free the obtained comm and info object */
mpi_ret = MPI_Comm_free(&comm_out);
VRFY((mpi_ret >= 0), "MPI_Comm_free succeeded");
mpi_ret = MPI_Info_free(&info_out);
VRFY((mpi_ret >= 0), "MPI_Info_free succeeded");
/* Copy the fapl and ensure it's equal to the original */
fapl_copy_id = H5Pcopy(fapl_id);
VRFY((fapl_copy_id != H5I_INVALID_HID), "H5Pcopy");
are_equal = H5Pequal(fapl_id, fapl_copy_id);
VRFY((TRUE == are_equal), "H5Pequal");
/* Add a property to the copy and ensure it's different now */
mpi_ret = MPI_Info_set(info, "hdf_info_prop2", "abc");
VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_set");
ret = H5Pset_mpi_params(fapl_copy_id, comm, info);
VRFY((ret >= 0), "H5Pset_mpi_params succeeded");
are_equal = H5Pequal(fapl_id, fapl_copy_id);
VRFY((FALSE == are_equal), "H5Pequal");
/* Add a property with the same key but a different value to the original
* and ensure they are still different.
*/
mpi_ret = MPI_Info_set(info, "hdf_info_prop2", "ijk");
VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_set");
ret = H5Pset_mpi_params(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_mpi_params succeeded");
are_equal = H5Pequal(fapl_id, fapl_copy_id);
VRFY((FALSE == are_equal), "H5Pequal");
/* Set the second property in the original to the same
* value as the copy and ensure they are the same now.
*/
mpi_ret = MPI_Info_set(info, "hdf_info_prop2", "abc");
VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_set");
ret = H5Pset_mpi_params(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_mpi_params succeeded");
are_equal = H5Pequal(fapl_id, fapl_copy_id);
VRFY((TRUE == are_equal), "H5Pequal");
/* create the file */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((fid != H5I_INVALID_HID), "H5Fcreate succeeded");
/* verify settings for file access properties */
/* Collective metadata writes */
ret = H5Pget_coll_metadata_write(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_coll_metadata_write succeeded");
VRFY((is_coll == FALSE), "Incorrect property setting for coll metadata writes");
/* Collective metadata read API calling requirement */
ret = H5Pget_all_coll_metadata_ops(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_all_coll_metadata_ops succeeded");
VRFY((is_coll == FALSE), "Incorrect property setting for coll metadata API calls requirement");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
/* Open the file with the MPI-IO driver */
ret = H5Pset_fapl_mpio(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_fapl_mpio failed");
fid = H5Fopen(filename, H5F_ACC_RDWR, fapl_id);
VRFY((fid != H5I_INVALID_HID), "H5Fcreate succeeded");
/* verify settings for file access properties */
/* Collective metadata writes */
ret = H5Pget_coll_metadata_write(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_coll_metadata_write succeeded");
VRFY((is_coll == FALSE), "Incorrect property setting for coll metadata writes");
/* Collective metadata read API calling requirement */
ret = H5Pget_all_coll_metadata_ops(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_all_coll_metadata_ops succeeded");
VRFY((is_coll == FALSE), "Incorrect property setting for coll metadata API calls requirement");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
/* Open the file with the MPI-IO driver w/ collective settings */
ret = H5Pset_fapl_mpio(fapl_id, comm, info);
VRFY((ret >= 0), "H5Pset_fapl_mpio failed");
/* Collective metadata writes */
ret = H5Pset_coll_metadata_write(fapl_id, TRUE);
VRFY((ret >= 0), "H5Pget_coll_metadata_write succeeded");
/* Collective metadata read API calling requirement */
ret = H5Pset_all_coll_metadata_ops(fapl_id, TRUE);
VRFY((ret >= 0), "H5Pget_all_coll_metadata_ops succeeded");
fid = H5Fopen(filename, H5F_ACC_RDWR, fapl_id);
VRFY((fid != H5I_INVALID_HID), "H5Fcreate succeeded");
/* verify settings for file access properties */
/* Collective metadata writes */
ret = H5Pget_coll_metadata_write(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_coll_metadata_write succeeded");
VRFY((is_coll == TRUE), "Incorrect property setting for coll metadata writes");
/* Collective metadata read API calling requirement */
ret = H5Pget_all_coll_metadata_ops(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_all_coll_metadata_ops succeeded");
VRFY((is_coll == TRUE), "Incorrect property setting for coll metadata API calls requirement");
/* close fapl and retrieve it from file */
ret = H5Pclose(fapl_id);
VRFY((ret >= 0), "H5Pclose succeeded");
fapl_id = H5I_INVALID_HID;
fapl_id = H5Fget_access_plist(fid);
VRFY((fapl_id != H5I_INVALID_HID), "H5P_FILE_ACCESS");
/* verify settings for file access properties */
/* Collective metadata writes */
ret = H5Pget_coll_metadata_write(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_coll_metadata_write succeeded");
VRFY((is_coll == TRUE), "Incorrect property setting for coll metadata writes");
/* Collective metadata read API calling requirement */
ret = H5Pget_all_coll_metadata_ops(fapl_id, &is_coll);
VRFY((ret >= 0), "H5Pget_all_coll_metadata_ops succeeded");
VRFY((is_coll == TRUE), "Incorrect property setting for coll metadata API calls requirement");
/* close file */
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
/* Release file-access plist */
ret = H5Pclose(fapl_id);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Pclose(fapl_copy_id);
VRFY((ret >= 0), "H5Pclose succeeded");
/* Free the MPI info object */
mpi_ret = MPI_Info_free(&info);
VRFY((mpi_ret >= 0), "MPI_Info_free succeeded");
} /* end test_file_properties() */
void
test_delete(void)
{
hid_t fid = H5I_INVALID_HID; /* HDF5 file ID */
hid_t fapl_id = H5I_INVALID_HID; /* File access plist */
const char *filename = NULL;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
htri_t is_hdf5 = FAIL; /* Whether a file is an HDF5 file */
herr_t ret; /* Generic return value */
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* setup file access plist */
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id != H5I_INVALID_HID), "H5Pcreate");
ret = H5Pset_fapl_mpio(fapl_id, comm, info);
VRFY((SUCCEED == ret), "H5Pset_fapl_mpio");
/* create the file */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((fid != H5I_INVALID_HID), "H5Fcreate");
/* close the file */
ret = H5Fclose(fid);
VRFY((SUCCEED == ret), "H5Fclose");
/* Verify that the file is an HDF5 file */
is_hdf5 = H5Fis_accessible(filename, fapl_id);
VRFY((TRUE == is_hdf5), "H5Fis_accessible");
/* Delete the file */
ret = H5Fdelete(filename, fapl_id);
VRFY((SUCCEED == ret), "H5Fdelete");
/* Verify that the file is NO LONGER an HDF5 file */
/* This should fail since there is no file */
H5E_BEGIN_TRY
{
is_hdf5 = H5Fis_accessible(filename, fapl_id);
}
H5E_END_TRY;
VRFY((is_hdf5 != SUCCEED), "H5Fis_accessible");
/* Release file-access plist */
ret = H5Pclose(fapl_id);
VRFY((SUCCEED == ret), "H5Pclose");
} /* end test_delete() */
+371
View File
@@ -0,0 +1,371 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Parallel tests for file image operations
*/
#include "hdf5.h"
#include "testphdf5.h"
/* file_image_daisy_chain_test
*
* Process zero:
*
* 1) Creates a core file with an integer vector data set of
* length n (= mpi_size),
*
* 2) Initializes the vector to zero in * location 0, and to -1
* everywhere else.
*
* 3) Flushes the core file, and gets an image of it. Closes
* the core file.
*
* 4) Sends the image to process 1.
*
* 5) Awaits receipt on a file image from process n-1.
*
* 6) opens the image received from process n-1, verifies that
* it contains a vector of length equal to mpi_size, and
* that the vector contains (0, 1, 2, ... n-1)
*
* 7) closes the core file and exits.
*
* Process i (0 < i < n)
*
* 1) Await receipt of file image from process (i - 1).
*
* 2) Open the image with the core file driver, verify that i
* contains a vector v of length, and that v[j] = j for
* 0 <= j < i, and that v[j] == -1 for i <= j < n
*
* 3) Set v[i] = i in the core file.
*
* 4) Flush the core file and send it to process (i + 1) % n.
*
* 5) close the core file and exit.
*
* Test fails on a hang (if an image is not received), or on invalid data.
*
* JRM -- 11/28/11
*/
void
file_image_daisy_chain_test(void)
{
char file_name[1024] = "\0";
int mpi_size, mpi_rank;
int mpi_result;
int i;
int space_ndims;
MPI_Status rcvstat;
int *vector_ptr = NULL;
hid_t fapl_id = -1;
hid_t file_id; /* file IDs */
hid_t dset_id = -1;
hid_t dset_type_id = -1;
hid_t space_id = -1;
herr_t err;
hsize_t dims[1];
void *image_ptr = NULL;
ssize_t bytes_read;
ssize_t image_len;
hbool_t vector_ok = TRUE;
htri_t tri_result;
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* setup file name */
HDsnprintf(file_name, 1024, "file_image_daisy_chain_test_%05d.h5", (int)mpi_rank);
if (mpi_rank == 0) {
/* 1) Creates a core file with an integer vector data set
* of length mpi_size,
*/
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id >= 0), "creating fapl");
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE);
VRFY((err >= 0), "setting core file driver in fapl.");
file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "created core file");
dims[0] = (hsize_t)mpi_size;
space_id = H5Screate_simple(1, dims, dims);
VRFY((space_id >= 0), "created data space");
dset_id = H5Dcreate2(file_id, "v", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "created data set");
/* 2) Initialize the vector to zero in location 0, and
* to -1 everywhere else.
*/
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
VRFY((vector_ptr != NULL), "allocated in memory representation of vector");
vector_ptr[0] = 0;
for (i = 1; i < mpi_size; i++)
vector_ptr[i] = -1;
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
VRFY((err >= 0), "wrote initial data to vector.");
HDfree(vector_ptr);
vector_ptr = NULL;
/* 3) Flush the core file, and get an image of it. Close
* the core file.
*/
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "flushed core file.");
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
VRFY((image_len > 0), "got image file size");
image_ptr = (void *)HDmalloc((size_t)image_len);
VRFY(image_ptr != NULL, "allocated file image buffer.");
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
VRFY(bytes_read == image_len, "wrote file into image buffer");
err = H5Sclose(space_id);
VRFY((err >= 0), "closed data space.");
err = H5Dclose(dset_id);
VRFY((err >= 0), "closed data set.");
err = H5Fclose(file_id);
VRFY((err >= 0), "closed core file(1).");
err = H5Pclose(fapl_id);
VRFY((err >= 0), "closed fapl(1).");
/* 4) Send the image to process 1. */
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, 1, 0, MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "sent image size to process 1");
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len, MPI_BYTE, 1, 0, MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "sent image to process 1");
HDfree(image_ptr);
image_ptr = NULL;
image_len = 0;
/* 5) Await receipt on a file image from process n-1. */
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, mpi_size - 1, 0,
MPI_COMM_WORLD, &rcvstat);
VRFY((mpi_result == MPI_SUCCESS), "received image len from process n-1");
image_ptr = (void *)HDmalloc((size_t)image_len);
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
mpi_result =
MPI_Recv((void *)image_ptr, (int)image_len, MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD, &rcvstat);
VRFY((mpi_result == MPI_SUCCESS), "received file image from process n-1");
/* 6) open the image received from process n-1, verify that
* it contains a vector of length equal to mpi_size, and
* that the vector contains (0, 1, 2, ... n-1).
*/
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id >= 0), "creating fapl");
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE);
VRFY((err >= 0), "setting core file driver in fapl.");
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
VRFY((err >= 0), "set file image in fapl.");
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
VRFY((file_id >= 0), "opened received file image file");
dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
VRFY((dset_id >= 0), "opened data set");
dset_type_id = H5Dget_type(dset_id);
VRFY((dset_type_id >= 0), "obtained data set type");
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
VRFY((tri_result == TRUE), "verified data set type");
space_id = H5Dget_space(dset_id);
VRFY((space_id >= 0), "opened data space");
space_ndims = H5Sget_simple_extent_ndims(space_id);
VRFY((space_ndims == 1), "verified data space num dims(1)");
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
VRFY((space_ndims == 1), "verified data space num dims(2)");
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
VRFY((err >= 0), "read received vector.");
vector_ok = TRUE;
for (i = 0; i < mpi_size; i++)
if (vector_ptr[i] != i)
vector_ok = FALSE;
VRFY((vector_ok), "verified received vector.");
HDfree(vector_ptr);
vector_ptr = NULL;
/* 7) closes the core file and exit. */
err = H5Sclose(space_id);
VRFY((err >= 0), "closed data space.");
err = H5Dclose(dset_id);
VRFY((err >= 0), "closed data set.");
err = H5Fclose(file_id);
VRFY((err >= 0), "closed core file(1).");
err = H5Pclose(fapl_id);
VRFY((err >= 0), "closed fapl(1).");
HDfree(image_ptr);
image_ptr = NULL;
image_len = 0;
}
else {
/* 1) Await receipt of file image from process (i - 1). */
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, mpi_rank - 1, 0,
MPI_COMM_WORLD, &rcvstat);
VRFY((mpi_result == MPI_SUCCESS), "received image size from process mpi_rank-1");
image_ptr = (void *)HDmalloc((size_t)image_len);
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
mpi_result =
MPI_Recv((void *)image_ptr, (int)image_len, MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD, &rcvstat);
VRFY((mpi_result == MPI_SUCCESS), "received file image from process mpi_rank-1");
/* 2) Open the image with the core file driver, verify that it
* contains a vector v of length, and that v[j] = j for
* 0 <= j < i, and that v[j] == -1 for i <= j < n
*/
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id >= 0), "creating fapl");
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE);
VRFY((err >= 0), "setting core file driver in fapl.");
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
VRFY((err >= 0), "set file image in fapl.");
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
H5Eprint2(H5P_DEFAULT, stderr);
VRFY((file_id >= 0), "opened received file image file");
dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
VRFY((dset_id >= 0), "opened data set");
dset_type_id = H5Dget_type(dset_id);
VRFY((dset_type_id >= 0), "obtained data set type");
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
VRFY((tri_result == TRUE), "verified data set type");
space_id = H5Dget_space(dset_id);
VRFY((space_id >= 0), "opened data space");
space_ndims = H5Sget_simple_extent_ndims(space_id);
VRFY((space_ndims == 1), "verified data space num dims(1)");
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
VRFY((space_ndims == 1), "verified data space num dims(2)");
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
VRFY((err >= 0), "read received vector.");
vector_ok = TRUE;
for (i = 0; i < mpi_size; i++) {
if (i < mpi_rank) {
if (vector_ptr[i] != i)
vector_ok = FALSE;
}
else {
if (vector_ptr[i] != -1)
vector_ok = FALSE;
}
}
VRFY((vector_ok), "verified received vector.");
/* 3) Set v[i] = i in the core file. */
vector_ptr[mpi_rank] = mpi_rank;
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
VRFY((err >= 0), "wrote modified data to vector.");
HDfree(vector_ptr);
vector_ptr = NULL;
/* 4) Flush the core file and send it to process (mpi_rank + 1) % n. */
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "flushed core file.");
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
VRFY((image_len > 0), "got (possibly modified) image file len");
image_ptr = (void *)HDrealloc((void *)image_ptr, (size_t)image_len);
VRFY(image_ptr != NULL, "re-allocated file image buffer.");
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
VRFY(bytes_read == image_len, "wrote file into image buffer");
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE,
(mpi_rank + 1) % mpi_size, 0, MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "sent image size to process (mpi_rank + 1) % mpi_size");
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len, MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "sent image to process (mpi_rank + 1) % mpi_size");
HDfree(image_ptr);
image_ptr = NULL;
image_len = 0;
/* 5) close the core file and exit. */
err = H5Sclose(space_id);
VRFY((err >= 0), "closed data space.");
err = H5Dclose(dset_id);
VRFY((err >= 0), "closed data set.");
err = H5Fclose(file_id);
VRFY((err >= 0), "closed core file(1).");
err = H5Pclose(fapl_id);
VRFY((err >= 0), "closed fapl(1).");
}
return;
} /* file_image_daisy_chain_test() */
+564
View File
@@ -0,0 +1,564 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* This verifies the correctness of parallel reading of a dataset that has been
* written serially using filters.
*
* Created by: Christian Chilan
* Date: 2007/05/15
*/
#include "hdf5.h"
#include "testphdf5.h"
#ifdef H5_HAVE_SZLIB_H
#include "szlib.h"
#endif
static int mpi_size, mpi_rank;
/* Chunk sizes */
#define CHUNK_DIM1 7
#define CHUNK_DIM2 27
/* Sizes of the vertical hyperslabs. Total dataset size is
{HS_DIM1, HS_DIM2 * mpi_size } */
#define HS_DIM1 200
#define HS_DIM2 100
const char *
h5_rmprefix(const char *filename)
{
const char *ret_ptr;
if ((ret_ptr = HDstrstr(filename, ":")) == NULL)
ret_ptr = filename;
else
ret_ptr++;
return (ret_ptr);
}
#ifdef H5_HAVE_FILTER_SZIP
/*-------------------------------------------------------------------------
* Function: h5_szip_can_encode
*
* Purpose: Retrieve the filter config flags for szip, tell if
* encoder is available.
*
* Return: 1: decode+encode is enabled
* 0: only decode is enabled
* -1: other
*
* Programmer:
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int
h5_szip_can_encode(void)
{
unsigned int filter_config_flags;
H5Zget_filter_info(H5Z_FILTER_SZIP, &filter_config_flags);
if ((filter_config_flags & (H5Z_FILTER_CONFIG_ENCODE_ENABLED | H5Z_FILTER_CONFIG_DECODE_ENABLED)) == 0) {
/* filter present but neither encode nor decode is supported (???) */
return -1;
}
else if ((filter_config_flags & (H5Z_FILTER_CONFIG_ENCODE_ENABLED | H5Z_FILTER_CONFIG_DECODE_ENABLED)) ==
H5Z_FILTER_CONFIG_DECODE_ENABLED) {
/* decoder only: read but not write */
return 0;
}
else if ((filter_config_flags & (H5Z_FILTER_CONFIG_ENCODE_ENABLED | H5Z_FILTER_CONFIG_DECODE_ENABLED)) ==
H5Z_FILTER_CONFIG_ENCODE_ENABLED) {
/* encoder only: write but not read (???) */
return -1;
}
else if ((filter_config_flags & (H5Z_FILTER_CONFIG_ENCODE_ENABLED | H5Z_FILTER_CONFIG_DECODE_ENABLED)) ==
(H5Z_FILTER_CONFIG_ENCODE_ENABLED | H5Z_FILTER_CONFIG_DECODE_ENABLED)) {
return 1;
}
return (-1);
}
#endif /* H5_HAVE_FILTER_SZIP */
/*-------------------------------------------------------------------------
* Function: filter_read_internal
*
* Purpose: Tests parallel reading of a 2D dataset written serially using
* filters. During the parallel reading phase, the dataset is
* divided evenly among the processors in vertical hyperslabs.
*
* Programmer: Christian Chilan
* Tuesday, May 15, 2007
*
*-------------------------------------------------------------------------
*/
static void
filter_read_internal(const char *filename, hid_t dcpl, hsize_t *dset_size)
{
hid_t file, dataset; /* HDF5 IDs */
hid_t access_plist; /* Access property list ID */
hid_t sid, memspace; /* Dataspace IDs */
hsize_t size[2]; /* Dataspace dimensions */
hsize_t hs_offset[2]; /* Hyperslab offset */
hsize_t hs_size[2]; /* Hyperslab size */
size_t i, j; /* Local index variables */
char name[32] = "dataset";
herr_t hrc; /* Error status */
int *points = NULL; /* Writing buffer for entire dataset */
int *check = NULL; /* Reading buffer for selected hyperslab */
(void)dset_size; /* silence compiler */
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* set sizes for dataset and hyperslabs */
hs_size[0] = size[0] = HS_DIM1;
hs_size[1] = HS_DIM2;
size[1] = hs_size[1] * (hsize_t)mpi_size;
hs_offset[0] = 0;
hs_offset[1] = hs_size[1] * (hsize_t)mpi_rank;
/* Create the data space */
sid = H5Screate_simple(2, size, NULL);
VRFY(sid >= 0, "H5Screate_simple");
/* Create buffers */
points = (int *)HDmalloc(size[0] * size[1] * sizeof(int));
VRFY(points != NULL, "HDmalloc");
check = (int *)HDmalloc(hs_size[0] * hs_size[1] * sizeof(int));
VRFY(check != NULL, "HDmalloc");
/* Initialize writing buffer with random data */
for (i = 0; i < size[0]; i++)
for (j = 0; j < size[1]; j++)
points[i * size[1] + j] = (int)(i + j + 7);
VRFY(H5Pall_filters_avail(dcpl), "Incorrect filter availability");
/* Serial write phase */
if (MAINPROCESS) {
file = H5Fcreate(h5_rmprefix(filename), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
VRFY(file >= 0, "H5Fcreate");
/* Create the dataset */
dataset = H5Dcreate2(file, name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY(dataset >= 0, "H5Dcreate2");
hrc = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points);
VRFY(hrc >= 0, "H5Dwrite");
#if 0
*dset_size = H5Dget_storage_size(dataset);
VRFY(*dset_size > 0, "H5Dget_storage_size");
#endif
hrc = H5Dclose(dataset);
VRFY(hrc >= 0, "H5Dclose");
hrc = H5Fclose(file);
VRFY(hrc >= 0, "H5Fclose");
}
MPI_Barrier(MPI_COMM_WORLD);
/* Parallel read phase */
/* Set up MPIO file access property lists */
access_plist = H5Pcreate(H5P_FILE_ACCESS);
VRFY((access_plist >= 0), "H5Pcreate");
hrc = H5Pset_fapl_mpio(access_plist, MPI_COMM_WORLD, MPI_INFO_NULL);
VRFY((hrc >= 0), "H5Pset_fapl_mpio");
/* Open the file */
file = H5Fopen(filename, H5F_ACC_RDWR, access_plist);
VRFY((file >= 0), "H5Fopen");
dataset = H5Dopen2(file, name, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dopen2");
hrc = H5Sselect_hyperslab(sid, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL);
VRFY(hrc >= 0, "H5Sselect_hyperslab");
memspace = H5Screate_simple(2, hs_size, NULL);
VRFY(memspace >= 0, "H5Screate_simple");
hrc = H5Dread(dataset, H5T_NATIVE_INT, memspace, sid, H5P_DEFAULT, check);
VRFY(hrc >= 0, "H5Dread");
/* Check that the values read are the same as the values written */
for (i = 0; i < hs_size[0]; i++) {
for (j = 0; j < hs_size[1]; j++) {
if (points[i * size[1] + (size_t)hs_offset[1] + j] != check[i * hs_size[1] + j]) {
HDfprintf(stderr, " Read different values than written.\n");
HDfprintf(stderr, " At index %lu,%lu\n", (unsigned long)(i),
(unsigned long)(hs_offset[1] + j));
HDfprintf(stderr, " At original: %d\n",
(int)points[i * size[1] + (size_t)hs_offset[1] + j]);
HDfprintf(stderr, " At returned: %d\n", (int)check[i * hs_size[1] + j]);
VRFY(FALSE, "");
}
}
}
#if 0
/* Get the storage size of the dataset */
*dset_size = H5Dget_storage_size(dataset);
VRFY(*dset_size != 0, "H5Dget_storage_size");
#endif
/* Clean up objects used for this test */
hrc = H5Dclose(dataset);
VRFY(hrc >= 0, "H5Dclose");
hrc = H5Sclose(sid);
VRFY(hrc >= 0, "H5Sclose");
hrc = H5Sclose(memspace);
VRFY(hrc >= 0, "H5Sclose");
hrc = H5Pclose(access_plist);
VRFY(hrc >= 0, "H5Pclose");
hrc = H5Fclose(file);
VRFY(hrc >= 0, "H5Fclose");
HDfree(points);
HDfree(check);
MPI_Barrier(MPI_COMM_WORLD);
}
/*-------------------------------------------------------------------------
* Function: test_filter_read
*
* Purpose: Tests parallel reading of datasets written serially using
* several (combinations of) filters.
*
* Programmer: Christian Chilan
* Tuesday, May 15, 2007
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
void
test_filter_read(void)
{
hid_t dc; /* HDF5 IDs */
const hsize_t chunk_size[2] = {CHUNK_DIM1, CHUNK_DIM2}; /* Chunk dimensions */
#if 0
hsize_t null_size; /* Size of dataset without filters */
#endif
unsigned chunk_opts; /* Chunk options */
unsigned disable_partial_chunk_filters; /* Whether filters are disabled on partial chunks */
herr_t hrc;
const char *filename;
#ifdef H5_HAVE_FILTER_FLETCHER32
hsize_t fletcher32_size; /* Size of dataset with Fletcher32 checksum */
#endif
#ifdef H5_HAVE_FILTER_DEFLATE
hsize_t deflate_size; /* Size of dataset with deflate filter */
#endif /* H5_HAVE_FILTER_DEFLATE */
#ifdef H5_HAVE_FILTER_SZIP
hsize_t szip_size; /* Size of dataset with szip filter */
unsigned szip_options_mask = H5_SZIP_NN_OPTION_MASK;
unsigned szip_pixels_per_block = 4;
#endif /* H5_HAVE_FILTER_SZIP */
#if 0
hsize_t shuffle_size; /* Size of dataset with shuffle filter */
#endif
#if (defined H5_HAVE_FILTER_DEFLATE || defined H5_HAVE_FILTER_SZIP)
hsize_t combo_size; /* Size of dataset with multiple filters */
#endif /* H5_HAVE_FILTER_DEFLATE || H5_HAVE_FILTER_SZIP */
filename = PARATESTFILE /* GetTestParameters() */;
if (VERBOSE_MED)
HDprintf("Parallel reading of dataset written with filters %s\n", filename);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FILTERS)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(
" API functions for basic file, dataset or filter aren't supported with this connector\n");
fflush(stdout);
}
return;
}
/*----------------------------------------------------------
* STEP 0: Test without filters.
*----------------------------------------------------------
*/
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
filter_read_internal(filename, dc, /* &null_size */ NULL);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
/* Run steps 1-3 both with and without filters disabled on partial chunks */
for (disable_partial_chunk_filters = 0; disable_partial_chunk_filters <= 1;
disable_partial_chunk_filters++) {
/* Set chunk options appropriately */
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_filter");
hrc = H5Pget_chunk_opts(dc, &chunk_opts);
VRFY(hrc >= 0, "H5Pget_chunk_opts");
if (disable_partial_chunk_filters)
chunk_opts |= H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS;
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
/*----------------------------------------------------------
* STEP 1: Test Fletcher32 Checksum by itself.
*----------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_FLETCHER32
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pset_filter");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_filter");
hrc = H5Pset_chunk_opts(dc, chunk_opts);
VRFY(hrc >= 0, "H5Pset_chunk_opts");
hrc = H5Pset_filter(dc, H5Z_FILTER_FLETCHER32, 0, 0, NULL);
VRFY(hrc >= 0, "H5Pset_filter");
filter_read_internal(filename, dc, &fletcher32_size);
VRFY(fletcher32_size > null_size, "Size after checksumming is incorrect.");
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
#endif /* H5_HAVE_FILTER_FLETCHER32 */
/*----------------------------------------------------------
* STEP 2: Test deflation by itself.
*----------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_DEFLATE
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_chunk_opts(dc, chunk_opts);
VRFY(hrc >= 0, "H5Pset_chunk_opts");
hrc = H5Pset_deflate(dc, 6);
VRFY(hrc >= 0, "H5Pset_deflate");
filter_read_internal(filename, dc, &deflate_size);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
#endif /* H5_HAVE_FILTER_DEFLATE */
/*----------------------------------------------------------
* STEP 3: Test szip compression by itself.
*----------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_SZIP
if (h5_szip_can_encode() == 1) {
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_chunk_opts(dc, chunk_opts);
VRFY(hrc >= 0, "H5Pset_chunk_opts");
hrc = H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block);
VRFY(hrc >= 0, "H5Pset_szip");
filter_read_internal(filename, dc, &szip_size);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
}
#endif /* H5_HAVE_FILTER_SZIP */
} /* end for */
/*----------------------------------------------------------
* STEP 4: Test shuffling by itself.
*----------------------------------------------------------
*/
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_shuffle(dc);
VRFY(hrc >= 0, "H5Pset_shuffle");
filter_read_internal(filename, dc, /* &shuffle_size */ NULL);
#if 0
VRFY(shuffle_size == null_size, "Shuffled size not the same as uncompressed size.");
#endif
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
/*----------------------------------------------------------
* STEP 5: Test shuffle + deflate + checksum in any order.
*----------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_DEFLATE
/* Testing shuffle+deflate+checksum filters (checksum first) */
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_fletcher32(dc);
VRFY(hrc >= 0, "H5Pset_fletcher32");
hrc = H5Pset_shuffle(dc);
VRFY(hrc >= 0, "H5Pset_shuffle");
hrc = H5Pset_deflate(dc, 6);
VRFY(hrc >= 0, "H5Pset_deflate");
filter_read_internal(filename, dc, &combo_size);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
/* Testing shuffle+deflate+checksum filters (checksum last) */
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_shuffle(dc);
VRFY(hrc >= 0, "H5Pset_shuffle");
hrc = H5Pset_deflate(dc, 6);
VRFY(hrc >= 0, "H5Pset_deflate");
hrc = H5Pset_fletcher32(dc);
VRFY(hrc >= 0, "H5Pset_fletcher32");
filter_read_internal(filename, dc, &combo_size);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
#endif /* H5_HAVE_FILTER_DEFLATE */
/*----------------------------------------------------------
* STEP 6: Test shuffle + szip + checksum in any order.
*----------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_SZIP
/* Testing shuffle+szip(with encoder)+checksum filters(checksum first) */
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_fletcher32(dc);
VRFY(hrc >= 0, "H5Pset_fletcher32");
hrc = H5Pset_shuffle(dc);
VRFY(hrc >= 0, "H5Pset_shuffle");
/* Make sure encoding is enabled */
if (h5_szip_can_encode() == 1) {
hrc = H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block);
VRFY(hrc >= 0, "H5Pset_szip");
filter_read_internal(filename, dc, &combo_size);
}
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
/* Testing shuffle+szip(with encoder)+checksum filters(checksum last) */
/* Make sure encoding is enabled */
if (h5_szip_can_encode() == 1) {
dc = H5Pcreate(H5P_DATASET_CREATE);
VRFY(dc >= 0, "H5Pcreate");
hrc = H5Pset_chunk(dc, 2, chunk_size);
VRFY(hrc >= 0, "H5Pset_chunk");
hrc = H5Pset_shuffle(dc);
VRFY(hrc >= 0, "H5Pset_shuffle");
hrc = H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block);
VRFY(hrc >= 0, "H5Pset_szip");
hrc = H5Pset_fletcher32(dc);
VRFY(hrc >= 0, "H5Pset_fletcher32");
filter_read_internal(filename, dc, &combo_size);
/* Clean up objects used for this test */
hrc = H5Pclose(dc);
VRFY(hrc >= 0, "H5Pclose");
}
#endif /* H5_HAVE_FILTER_SZIP */
}
+2814
View File
@@ -0,0 +1,2814 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "hdf5.h"
#include "testphdf5.h"
#if 0
#include "H5Dprivate.h"
#include "H5private.h"
#endif
#define DIM 2
#define SIZE 32
#define NDATASET 4
#define GROUP_DEPTH 32
enum obj_type { is_group, is_dset };
static int get_size(void);
static void write_dataset(hid_t, hid_t, hid_t);
static int read_dataset(hid_t, hid_t, hid_t);
static void create_group_recursive(hid_t, hid_t, hid_t, int);
static void recursive_read_group(hid_t, hid_t, hid_t, int);
static void group_dataset_read(hid_t fid, int mpi_rank, int m);
static void write_attribute(hid_t, int, int);
static int read_attribute(hid_t, int, int);
static int check_value(DATATYPE *, DATATYPE *, int);
static void get_slab(hsize_t[], hsize_t[], hsize_t[], hsize_t[], int);
/*
* The size value computed by this function is used extensively in
* configuring tests for the current number of processes.
*
* This function was created as part of an effort to allow the
* test functions in this file to run on an arbitrary number of
* processors.
* JRM - 8/11/04
*/
static int
get_size(void)
{
int mpi_rank;
int mpi_size;
int size = SIZE;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); /* needed for VRFY */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
if (mpi_size > size) {
if ((mpi_size % 2) == 0) {
size = mpi_size;
}
else {
size = mpi_size + 1;
}
}
VRFY((mpi_size <= size), "mpi_size <= size");
VRFY(((size % 2) == 0), "size isn't even");
return (size);
} /* get_size() */
/*
* Example of using PHDF5 to create a zero sized dataset.
*
*/
void
zero_dim_dset(void)
{
int mpi_size, mpi_rank;
const char *filename;
hid_t fid, plist, dcpl, dsid, sid;
hsize_t dim, chunk_dim;
herr_t ret;
int data[1];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((plist >= 0), "create_faccess_plist succeeded");
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
VRFY((fid >= 0), "H5Fcreate succeeded");
ret = H5Pclose(plist);
VRFY((ret >= 0), "H5Pclose succeeded");
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "failed H5Pcreate");
/* Set 1 chunk size */
chunk_dim = 1;
ret = H5Pset_chunk(dcpl, 1, &chunk_dim);
VRFY((ret >= 0), "failed H5Pset_chunk");
/* Create 1D dataspace with 0 dim size */
dim = 0;
sid = H5Screate_simple(1, &dim, NULL);
VRFY((sid >= 0), "failed H5Screate_simple");
/* Create chunked dataset */
dsid = H5Dcreate2(fid, "dset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dsid >= 0), "failed H5Dcreate2");
/* write 0 elements from dataset */
ret = H5Dwrite(dsid, H5T_NATIVE_INT, sid, sid, H5P_DEFAULT, data);
VRFY((ret >= 0), "failed H5Dwrite");
/* Read 0 elements from dataset */
ret = H5Dread(dsid, H5T_NATIVE_INT, sid, sid, H5P_DEFAULT, data);
VRFY((ret >= 0), "failed H5Dread");
H5Pclose(dcpl);
H5Dclose(dsid);
H5Sclose(sid);
H5Fclose(fid);
}
/*
* Example of using PHDF5 to create ndatasets datasets. Each process write
* a slab of array to the file.
*/
void
multiple_dset_write(void)
{
int i, j, n, mpi_size, mpi_rank, size;
hid_t iof, plist, dataset, memspace, filespace;
hid_t dcpl; /* Dataset creation property list */
hsize_t chunk_origin[DIM];
hsize_t chunk_dims[DIM], file_dims[DIM];
hsize_t count[DIM] = {1, 1};
double *outme = NULL;
double fill = 1.0; /* Fill value */
char dname[100];
herr_t ret;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
int ndatasets;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
/* ndatasets = pt->count; */ ndatasets = NDATASETS;
size = get_size();
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
outme = HDmalloc((size_t)size * (size_t)size * sizeof(double));
VRFY((outme != NULL), "HDmalloc succeeded for outme");
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((plist >= 0), "create_faccess_plist succeeded");
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
VRFY((iof >= 0), "H5Fcreate succeeded");
ret = H5Pclose(plist);
VRFY((ret >= 0), "H5Pclose succeeded");
/* decide the hyperslab according to process number. */
get_slab(chunk_origin, chunk_dims, count, file_dims, size);
memspace = H5Screate_simple(DIM, chunk_dims, NULL);
filespace = H5Screate_simple(DIM, file_dims, NULL);
ret = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
VRFY((ret >= 0), "mdata hyperslab selection");
/* Create a dataset creation property list */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "dataset creation property list succeeded");
ret = H5Pset_fill_value(dcpl, H5T_NATIVE_DOUBLE, &fill);
VRFY((ret >= 0), "set fill-value succeeded");
for (n = 0; n < ndatasets; n++) {
HDsnprintf(dname, sizeof(dname), "dataset %d", n);
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset > 0), dname);
/* calculate data to write */
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
outme[(i * size) + j] = n * 1000 + mpi_rank;
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, memspace, filespace, H5P_DEFAULT, outme);
H5Dclose(dataset);
#ifdef BARRIER_CHECKS
if (!((n + 1) % 10)) {
HDprintf("created %d datasets\n", n + 1);
MPI_Barrier(MPI_COMM_WORLD);
}
#endif /* BARRIER_CHECKS */
}
H5Sclose(filespace);
H5Sclose(memspace);
H5Pclose(dcpl);
H5Fclose(iof);
HDfree(outme);
}
/* Example of using PHDF5 to create, write, and read compact dataset.
*/
void
compact_dataset(void)
{
int i, j, mpi_size, mpi_rank, size, err_num = 0;
hid_t iof, plist, dcpl, dxpl, dataset, filespace;
hsize_t file_dims[DIM];
double *outme;
double *inme;
char dname[] = "dataset";
herr_t ret;
const char *filename;
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
hbool_t prop_value;
#endif
size = get_size();
for (i = 0; i < DIM; i++)
file_dims[i] = (hsize_t)size;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
outme = HDmalloc((size_t)((size_t)size * (size_t)size * sizeof(double)));
VRFY((outme != NULL), "HDmalloc succeeded for outme");
inme = HDmalloc((size_t)size * (size_t)size * sizeof(double));
VRFY((outme != NULL), "HDmalloc succeeded for inme");
filename = PARATESTFILE /* GetTestParameters() */;
VRFY((mpi_size <= size), "mpi_size <= size");
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
/* Define data space */
filespace = H5Screate_simple(DIM, file_dims, NULL);
/* Create a compact dataset */
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "dataset creation property list succeeded");
ret = H5Pset_layout(dcpl, H5D_COMPACT);
VRFY((dcpl >= 0), "set property list for compact dataset");
ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY);
VRFY((ret >= 0), "set space allocation time for compact dataset");
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
/* set up the collective transfer properties list */
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Recalculate data to write. Each process writes the same data. */
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
outme[(i * size) + j] = (i + j) * 1000;
ret = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, dxpl, outme);
VRFY((ret >= 0), "H5Dwrite succeeded");
H5Pclose(dcpl);
H5Pclose(plist);
H5Dclose(dataset);
H5Sclose(filespace);
H5Fclose(iof);
/* Open the file and dataset, read and compare the data. */
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
iof = H5Fopen(filename, H5F_ACC_RDONLY, plist);
VRFY((iof >= 0), "H5Fopen succeeded");
/* set up the collective transfer properties list */
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
dataset = H5Dopen2(iof, dname, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dopen2 succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = H5D_XFER_COLL_RANK0_BCAST_DEF;
ret = H5Pinsert2(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, H5D_XFER_COLL_RANK0_BCAST_SIZE, &prop_value, NULL,
NULL, NULL, NULL, NULL, NULL);
VRFY((ret >= 0), "H5Pinsert2() succeeded");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
ret = H5Dread(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, dxpl, inme);
VRFY((ret >= 0), "H5Dread succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = FALSE;
ret = H5Pget(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, &prop_value);
VRFY((ret >= 0), "H5Pget succeeded");
VRFY((prop_value == FALSE && dxfer_coll_type == DXFER_COLLECTIVE_IO),
"rank 0 Bcast optimization was performed for a compact dataset");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
/* Verify data value */
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
if (!H5_DBL_ABS_EQUAL(inme[(i * size) + j], outme[(i * size) + j]))
if (err_num++ < MAX_ERR_REPORT || VERBOSE_MED)
HDprintf("Dataset Verify failed at [%d][%d]: expect %f, got %f\n", i, j,
outme[(i * size) + j], inme[(i * size) + j]);
H5Pclose(plist);
H5Pclose(dxpl);
H5Dclose(dataset);
H5Fclose(iof);
HDfree(inme);
HDfree(outme);
}
/*
* Example of using PHDF5 to create, write, and read dataset and attribute
* of Null dataspace.
*/
void
null_dataset(void)
{
int mpi_size, mpi_rank;
hid_t iof, plist, dxpl, dataset, attr, sid;
unsigned uval = 2; /* Buffer for writing to dataset */
int val = 1; /* Buffer for writing to attribute */
hssize_t nelem;
char dname[] = "dataset";
char attr_name[] = "attribute";
herr_t ret;
const char *filename;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset, or attribute aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
/* Define data space */
sid = H5Screate(H5S_NULL);
/* Check that the null dataspace actually has 0 elements */
nelem = H5Sget_simple_extent_npoints(sid);
VRFY((nelem == 0), "H5Sget_simple_extent_npoints");
/* Create a compact dataset */
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
/* set up the collective transfer properties list */
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Write "nothing" to the dataset(with type conversion) */
ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, &uval);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* Create an attribute for the group */
attr = H5Acreate2(dataset, attr_name, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT);
VRFY((attr >= 0), "H5Acreate2");
/* Write "nothing" to the attribute(with type conversion) */
ret = H5Awrite(attr, H5T_NATIVE_INT, &val);
VRFY((ret >= 0), "H5Awrite");
H5Aclose(attr);
H5Dclose(dataset);
H5Pclose(plist);
H5Sclose(sid);
H5Fclose(iof);
/* Open the file and dataset, read and compare the data. */
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
iof = H5Fopen(filename, H5F_ACC_RDONLY, plist);
VRFY((iof >= 0), "H5Fopen succeeded");
/* set up the collective transfer properties list */
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pcreate xfer succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
dataset = H5Dopen2(iof, dname, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dopen2 succeeded");
/* Try reading from the dataset(make certain our buffer is unmodified) */
ret = H5Dread(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, dxpl, &uval);
VRFY((ret >= 0), "H5Dread");
VRFY((uval == 2), "H5Dread");
/* Open the attribute for the dataset */
attr = H5Aopen(dataset, attr_name, H5P_DEFAULT);
VRFY((attr >= 0), "H5Aopen");
/* Try reading from the attribute(make certain our buffer is unmodified) */ ret =
H5Aread(attr, H5T_NATIVE_INT, &val);
VRFY((ret >= 0), "H5Aread");
VRFY((val == 1), "H5Aread");
H5Pclose(plist);
H5Pclose(dxpl);
H5Aclose(attr);
H5Dclose(dataset);
H5Fclose(iof);
}
/* Example of using PHDF5 to create "large" datasets. (>2GB, >4GB, >8GB)
* Actual data is _not_ written to these datasets. Dataspaces are exact
* sizes(2GB, 4GB, etc.), but the metadata for the file pushes the file over
* the boundary of interest.
*/
void
big_dataset(void)
{
int mpi_size, mpi_rank; /* MPI info */
hid_t iof, /* File ID */
fapl, /* File access property list ID */
dataset, /* Dataset ID */
filespace; /* Dataset's dataspace ID */
hsize_t file_dims[4]; /* Dimensions of dataspace */
char dname[] = "dataset"; /* Name of dataset */
#if 0
MPI_Offset file_size; /* Size of file on disk */
#endif
herr_t ret; /* Generic return value */
const char *filename;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
/* Verify MPI_Offset can handle larger than 2GB sizes */
VRFY((sizeof(MPI_Offset) > 4), "sizeof(MPI_Offset)>4");
filename = PARATESTFILE /* GetTestParameters() */;
fapl = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl >= 0), "create_faccess_plist succeeded");
/*
* Create >2GB HDF5 file
*/
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((iof >= 0), "H5Fcreate succeeded");
/* Define dataspace for 2GB dataspace */
file_dims[0] = 2;
file_dims[1] = 1024;
file_dims[2] = 1024;
file_dims[3] = 1024;
filespace = H5Screate_simple(4, file_dims, NULL);
VRFY((filespace >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_UCHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
/* Close all file objects */
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(filespace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(iof);
VRFY((ret >= 0), "H5Fclose succeeded");
#if 0
/* Check that file of the correct size was created */
file_size = h5_get_file_size(filename, fapl);
VRFY((file_size == 2147485696ULL), "File is correct size(~2GB)");
#endif
/*
* Create >4GB HDF5 file
*/
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((iof >= 0), "H5Fcreate succeeded");
/* Define dataspace for 4GB dataspace */
file_dims[0] = 4;
file_dims[1] = 1024;
file_dims[2] = 1024;
file_dims[3] = 1024;
filespace = H5Screate_simple(4, file_dims, NULL);
VRFY((filespace >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_UCHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
/* Close all file objects */
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(filespace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(iof);
VRFY((ret >= 0), "H5Fclose succeeded");
#if 0
/* Check that file of the correct size was created */
file_size = h5_get_file_size(filename, fapl);
VRFY((file_size == 4294969344ULL), "File is correct size(~4GB)");
#endif
/*
* Create >8GB HDF5 file
*/
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((iof >= 0), "H5Fcreate succeeded");
/* Define dataspace for 8GB dataspace */
file_dims[0] = 8;
file_dims[1] = 1024;
file_dims[2] = 1024;
file_dims[3] = 1024;
filespace = H5Screate_simple(4, file_dims, NULL);
VRFY((filespace >= 0), "H5Screate_simple succeeded");
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_UCHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
/* Close all file objects */
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(filespace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(iof);
VRFY((ret >= 0), "H5Fclose succeeded");
#if 0
/* Check that file of the correct size was created */
file_size = h5_get_file_size(filename, fapl);
VRFY((file_size == 8589936640ULL), "File is correct size(~8GB)");
#endif
/* Close fapl */
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
}
/* Example of using PHDF5 to read a partial written dataset. The dataset does
* not have actual data written to the entire raw data area and relies on the
* default fill value of zeros to work correctly.
*/
void
dataset_fillvalue(void)
{
int mpi_size, mpi_rank; /* MPI info */
int err_num; /* Number of errors */
hid_t iof, /* File ID */
fapl, /* File access property list ID */
dxpl, /* Data transfer property list ID */
dataset, /* Dataset ID */
memspace, /* Memory dataspace ID */
filespace; /* Dataset's dataspace ID */
char dname[] = "dataset"; /* Name of dataset */
hsize_t dset_dims[4] = {0, 6, 7, 8};
hsize_t req_start[4] = {0, 0, 0, 0};
hsize_t req_count[4] = {1, 6, 7, 8};
hsize_t dset_size; /* Dataset size */
int *rdata, *wdata; /* Buffers for data to read and write */
int *twdata, *trdata; /* Temporary pointer into buffer */
int acc, i, ii, j, k, l; /* Local index variables */
herr_t ret; /* Generic return value */
const char *filename;
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
hbool_t prop_value;
#endif
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
filename = PARATESTFILE /* GetTestParameters() */;
/* Set the dataset dimension to be one row more than number of processes */
/* and calculate the actual dataset size. */
dset_dims[0] = (hsize_t)(mpi_size + 1);
dset_size = dset_dims[0] * dset_dims[1] * dset_dims[2] * dset_dims[3];
/* Allocate space for the buffers */
rdata = HDmalloc((size_t)(dset_size * sizeof(int)));
VRFY((rdata != NULL), "HDcalloc succeeded for read buffer");
wdata = HDmalloc((size_t)(dset_size * sizeof(int)));
VRFY((wdata != NULL), "HDmalloc succeeded for write buffer");
fapl = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl >= 0), "create_faccess_plist succeeded");
/*
* Create HDF5 file
*/
iof = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((iof >= 0), "H5Fcreate succeeded");
filespace = H5Screate_simple(4, dset_dims, NULL);
VRFY((filespace >= 0), "File H5Screate_simple succeeded");
dataset = H5Dcreate2(iof, dname, H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset >= 0), "H5Dcreate2 succeeded");
memspace = H5Screate_simple(4, dset_dims, NULL);
VRFY((memspace >= 0), "Memory H5Screate_simple succeeded");
/*
* Read dataset before any data is written.
*/
/* Create DXPL for I/O */
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "H5Pcreate succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = H5D_XFER_COLL_RANK0_BCAST_DEF;
ret = H5Pinsert2(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, H5D_XFER_COLL_RANK0_BCAST_SIZE, &prop_value, NULL,
NULL, NULL, NULL, NULL, NULL);
VRFY((ret >= 0), "testing property list inserted succeeded");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
for (ii = 0; ii < 2; ii++) {
if (ii == 0)
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_INDEPENDENT);
else
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* set entire read buffer with the constant 2 */
HDmemset(rdata, 2, (size_t)(dset_size * sizeof(int)));
/* Read the entire dataset back */
ret = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, rdata);
VRFY((ret >= 0), "H5Dread succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = FALSE;
ret = H5Pget(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, &prop_value);
VRFY((ret >= 0), "testing property list get succeeded");
if (ii == 0)
VRFY((prop_value == FALSE), "correctly handled rank 0 Bcast");
else
VRFY((prop_value == TRUE), "correctly handled rank 0 Bcast");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
/* Verify all data read are the fill value 0 */
trdata = rdata;
err_num = 0;
for (i = 0; i < (int)dset_dims[0]; i++)
for (j = 0; j < (int)dset_dims[1]; j++)
for (k = 0; k < (int)dset_dims[2]; k++)
for (l = 0; l < (int)dset_dims[3]; l++, trdata++)
if (*trdata != 0)
if (err_num++ < MAX_ERR_REPORT || VERBOSE_MED)
HDprintf(
"Rank %d: Dataset Verify failed at [%d][%d][%d][%d]: expect 0, got %d\n",
mpi_rank, i, j, k, l, *trdata);
if (err_num > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("Rank %d: [more errors ...]\n", mpi_rank);
if (err_num) {
HDprintf("Rank %d: %d errors found in check_value\n", mpi_rank, err_num);
nerrors++;
}
}
/* Barrier to ensure all processes have completed the above test. */
MPI_Barrier(MPI_COMM_WORLD);
/*
* Each process writes 1 row of data. Thus last row is not written.
*/
/* Create hyperslabs in memory and file dataspaces */
req_start[0] = (hsize_t)mpi_rank;
ret = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, req_start, NULL, req_count, NULL);
VRFY((ret >= 0), "H5Sselect_hyperslab succeeded on memory dataspace");
ret = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, req_start, NULL, req_count, NULL);
VRFY((ret >= 0), "H5Sselect_hyperslab succeeded on memory dataspace");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Fill write buffer with some values */
twdata = wdata;
for (i = 0, acc = 0; i < (int)dset_dims[0]; i++)
for (j = 0; j < (int)dset_dims[1]; j++)
for (k = 0; k < (int)dset_dims[2]; k++)
for (l = 0; l < (int)dset_dims[3]; l++)
*twdata++ = acc++;
/* Collectively write a hyperslab of data to the dataset */
ret = H5Dwrite(dataset, H5T_NATIVE_INT, memspace, filespace, dxpl, wdata);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* Barrier here, to allow processes to sync */
MPI_Barrier(MPI_COMM_WORLD);
/*
* Read dataset after partial write.
*/
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = H5D_XFER_COLL_RANK0_BCAST_DEF;
ret = H5Pset(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, &prop_value);
VRFY((ret >= 0), " H5Pset succeeded");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
for (ii = 0; ii < 2; ii++) {
if (ii == 0)
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_INDEPENDENT);
else
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* set entire read buffer with the constant 2 */
HDmemset(rdata, 2, (size_t)(dset_size * sizeof(int)));
/* Read the entire dataset back */
ret = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, rdata);
VRFY((ret >= 0), "H5Dread succeeded");
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
prop_value = FALSE;
ret = H5Pget(dxpl, H5D_XFER_COLL_RANK0_BCAST_NAME, &prop_value);
VRFY((ret >= 0), "testing property list get succeeded");
if (ii == 0)
VRFY((prop_value == FALSE), "correctly handled rank 0 Bcast");
else
VRFY((prop_value == TRUE), "correctly handled rank 0 Bcast");
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
/* Verify correct data read */
twdata = wdata;
trdata = rdata;
err_num = 0;
for (i = 0; i < (int)dset_dims[0]; i++)
for (j = 0; j < (int)dset_dims[1]; j++)
for (k = 0; k < (int)dset_dims[2]; k++)
for (l = 0; l < (int)dset_dims[3]; l++, twdata++, trdata++)
if (i < mpi_size) {
if (*twdata != *trdata)
if (err_num++ < MAX_ERR_REPORT || VERBOSE_MED)
HDprintf("Dataset Verify failed at [%d][%d][%d][%d]: expect %d, got %d\n",
i, j, k, l, *twdata, *trdata);
} /* end if */
else {
if (*trdata != 0)
if (err_num++ < MAX_ERR_REPORT || VERBOSE_MED)
HDprintf("Dataset Verify failed at [%d][%d][%d][%d]: expect 0, got %d\n",
i, j, k, l, *trdata);
} /* end else */
if (err_num > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (err_num) {
HDprintf("%d errors found in check_value\n", err_num);
nerrors++;
}
}
/* Close all file objects */
ret = H5Dclose(dataset);
VRFY((ret >= 0), "H5Dclose succeeded");
ret = H5Sclose(filespace);
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Fclose(iof);
VRFY((ret >= 0), "H5Fclose succeeded");
/* Close memory dataspace */
ret = H5Sclose(memspace);
VRFY((ret >= 0), "H5Sclose succeeded");
/* Close dxpl */
ret = H5Pclose(dxpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* Close fapl */
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* free the buffers */
HDfree(rdata);
HDfree(wdata);
}
/* combined cngrpw and ingrpr tests because ingrpr reads file created by cngrpw. */
void
collective_group_write_independent_group_read(void)
{
collective_group_write();
independent_group_read();
}
/* Write multiple groups with a chunked dataset in each group collectively.
* These groups and datasets are for testing independent read later.
*/
void
collective_group_write(void)
{
int mpi_rank, mpi_size, size;
int i, j, m;
char gname[64], dname[32];
hid_t fid, gid, did, plist, dcpl, memspace, filespace;
DATATYPE *outme = NULL;
hsize_t chunk_origin[DIM];
hsize_t chunk_dims[DIM], file_dims[DIM], count[DIM];
hsize_t chunk_size[2]; /* Chunk dimensions - computed shortly */
herr_t ret1, ret2;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
int ngroups;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
/* ngroups = pt->count; */ ngroups = NGROUPS;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(
" API functions for basic file, group, or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
size = get_size();
chunk_size[0] = (hsize_t)(size / 2);
chunk_size[1] = (hsize_t)(size / 2);
outme = HDmalloc((size_t)size * (size_t)size * sizeof(DATATYPE));
VRFY((outme != NULL), "HDmalloc succeeded for outme");
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
VRFY((fid >= 0), "H5Fcreate");
H5Pclose(plist);
/* decide the hyperslab according to process number. */
get_slab(chunk_origin, chunk_dims, count, file_dims, size);
/* select hyperslab in memory and file spaces. These two operations are
* identical since the datasets are the same. */
memspace = H5Screate_simple(DIM, file_dims, NULL);
ret1 = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
filespace = H5Screate_simple(DIM, file_dims, NULL);
ret2 = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
VRFY((memspace >= 0), "memspace");
VRFY((filespace >= 0), "filespace");
VRFY((ret1 == 0), "mgroup memspace selection");
VRFY((ret2 == 0), "mgroup filespace selection");
dcpl = H5Pcreate(H5P_DATASET_CREATE);
ret1 = H5Pset_chunk(dcpl, 2, chunk_size);
VRFY((dcpl >= 0), "dataset creation property");
VRFY((ret1 == 0), "set chunk for dataset creation property");
/* creates ngroups groups under the root group, writes chunked
* datasets in parallel. */
for (m = 0; m < ngroups; m++) {
HDsnprintf(gname, sizeof(gname), "group%d", m);
gid = H5Gcreate2(fid, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((gid > 0), gname);
HDsnprintf(dname, sizeof(dname), "dataset%d", m);
did = H5Dcreate2(gid, dname, H5T_NATIVE_INT, filespace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
VRFY((did > 0), dname);
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
outme[(i * size) + j] = (i + j) * 1000 + mpi_rank;
ret1 = H5Dwrite(did, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, outme);
VRFY((ret1 == 0), "H5Dwrite");
ret1 = H5Dclose(did);
VRFY((ret1 == 0), "H5Dclose");
ret1 = H5Gclose(gid);
VRFY((ret1 == 0), "H5Gclose");
#ifdef BARRIER_CHECKS
if (!((m + 1) % 10)) {
HDprintf("created %d groups\n", m + 1);
MPI_Barrier(MPI_COMM_WORLD);
}
#endif /* BARRIER_CHECKS */
}
H5Pclose(dcpl);
H5Sclose(filespace);
H5Sclose(memspace);
ret1 = H5Fclose(fid);
VRFY((ret1 == 0), "H5Fclose");
HDfree(outme);
}
/* Let two sets of processes open and read different groups and chunked
* datasets independently.
*/
void
independent_group_read(void)
{
int mpi_rank, m;
hid_t plist, fid;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
int ngroups;
herr_t ret;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
/* ngroups = pt->count; */ ngroups = NGROUPS;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
H5Pset_all_coll_metadata_ops(plist, FALSE);
fid = H5Fopen(filename, H5F_ACC_RDONLY, plist);
VRFY((fid > 0), "H5Fopen");
H5Pclose(plist);
/* open groups and read datasets. Odd number processes read even number
* groups from the end; even number processes read odd number groups
* from the beginning. */
if (mpi_rank % 2 == 0) {
for (m = ngroups - 1; m == 0; m -= 2)
group_dataset_read(fid, mpi_rank, m);
}
else {
for (m = 0; m < ngroups; m += 2)
group_dataset_read(fid, mpi_rank, m);
}
ret = H5Fclose(fid);
VRFY((ret == 0), "H5Fclose");
}
/* Open and read datasets and compare data
*/
static void
group_dataset_read(hid_t fid, int mpi_rank, int m)
{
int ret, i, j, size;
char gname[64], dname[32];
hid_t gid, did;
DATATYPE *outdata = NULL;
DATATYPE *indata = NULL;
size = get_size();
indata = (DATATYPE *)HDmalloc((size_t)size * (size_t)size * sizeof(DATATYPE));
VRFY((indata != NULL), "HDmalloc succeeded for indata");
outdata = (DATATYPE *)HDmalloc((size_t)size * (size_t)size * sizeof(DATATYPE));
VRFY((outdata != NULL), "HDmalloc succeeded for outdata");
/* open every group under root group. */
HDsnprintf(gname, sizeof(gname), "group%d", m);
gid = H5Gopen2(fid, gname, H5P_DEFAULT);
VRFY((gid > 0), gname);
/* check the data. */
HDsnprintf(dname, sizeof(dname), "dataset%d", m);
did = H5Dopen2(gid, dname, H5P_DEFAULT);
VRFY((did > 0), dname);
H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, indata);
/* this is the original value */
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
outdata[(i * size) + j] = (i + j) * 1000 + mpi_rank;
/* compare the original value(outdata) to the value in file(indata).*/
ret = check_value(indata, outdata, size);
VRFY((ret == 0), "check the data");
ret = H5Dclose(did);
VRFY((ret == 0), "H5Dclose");
ret = H5Gclose(gid);
VRFY((ret == 0), "H5Gclose");
HDfree(indata);
HDfree(outdata);
}
/*
* Example of using PHDF5 to create multiple groups. Under the root group,
* it creates ngroups groups. Under the first group just created, it creates
* recursive subgroups of depth GROUP_DEPTH. In each created group, it
* generates NDATASETS datasets. Each process write a hyperslab of an array
* into the file. The structure is like
*
* root group
* |
* ---------------------------- ... ... ------------------------
* | | | ... ... | |
* group0*+' group1*+' group2*+' ... ... group ngroups*+'
* |
* 1st_child_group*'
* |
* 2nd_child_group*'
* |
* :
* :
* |
* GROUP_DEPTHth_child_group*'
*
* * means the group has dataset(s).
* + means the group has attribute(s).
* ' means the datasets in the groups have attribute(s).
*
*/
void
multiple_group_write(void)
{
int mpi_rank, mpi_size, size;
int m;
char gname[64];
hid_t fid, gid, plist, memspace, filespace;
hsize_t chunk_origin[DIM];
hsize_t chunk_dims[DIM], file_dims[DIM], count[DIM];
herr_t ret;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
int ngroups;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
/* ngroups = pt->count; */ ngroups = NGROUPS;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, group, dataset, or attribute aren't supported with "
"this connector\n");
fflush(stdout);
}
return;
}
size = get_size();
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
H5Pclose(plist);
/* decide the hyperslab according to process number. */
get_slab(chunk_origin, chunk_dims, count, file_dims, size);
/* select hyperslab in memory and file spaces. These two operations are
* identical since the datasets are the same. */
memspace = H5Screate_simple(DIM, file_dims, NULL);
VRFY((memspace >= 0), "memspace");
ret = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
VRFY((ret >= 0), "mgroup memspace selection");
filespace = H5Screate_simple(DIM, file_dims, NULL);
VRFY((filespace >= 0), "filespace");
ret = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
VRFY((ret >= 0), "mgroup filespace selection");
/* creates ngroups groups under the root group, writes datasets in
* parallel. */
for (m = 0; m < ngroups; m++) {
HDsnprintf(gname, sizeof(gname), "group%d", m);
gid = H5Gcreate2(fid, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((gid > 0), gname);
/* create attribute for these groups. */
write_attribute(gid, is_group, m);
if (m != 0)
write_dataset(memspace, filespace, gid);
H5Gclose(gid);
#ifdef BARRIER_CHECKS
if (!((m + 1) % 10)) {
HDprintf("created %d groups\n", m + 1);
MPI_Barrier(MPI_COMM_WORLD);
}
#endif /* BARRIER_CHECKS */
}
/* recursively creates subgroups under the first group. */
gid = H5Gopen2(fid, "group0", H5P_DEFAULT);
create_group_recursive(memspace, filespace, gid, 0);
ret = H5Gclose(gid);
VRFY((ret >= 0), "H5Gclose");
ret = H5Sclose(filespace);
VRFY((ret >= 0), "H5Sclose");
ret = H5Sclose(memspace);
VRFY((ret >= 0), "H5Sclose");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose");
}
/*
* In a group, creates NDATASETS datasets. Each process writes a hyperslab
* of a data array to the file.
*/
static void
write_dataset(hid_t memspace, hid_t filespace, hid_t gid)
{
int i, j, n, size;
int mpi_rank, mpi_size;
char dname[32];
DATATYPE *outme = NULL;
hid_t did;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
size = get_size();
outme = HDmalloc((size_t)size * (size_t)size * sizeof(double));
VRFY((outme != NULL), "HDmalloc succeeded for outme");
for (n = 0; n < NDATASET; n++) {
HDsnprintf(dname, sizeof(dname), "dataset%d", n);
did = H5Dcreate2(gid, dname, H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((did > 0), dname);
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
outme[(i * size) + j] = n * 1000 + mpi_rank;
H5Dwrite(did, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, outme);
/* create attribute for these datasets.*/
write_attribute(did, is_dset, n);
H5Dclose(did);
}
HDfree(outme);
}
/*
* Creates subgroups of depth GROUP_DEPTH recursively. Also writes datasets
* in parallel in each group.
*/
static void
create_group_recursive(hid_t memspace, hid_t filespace, hid_t gid, int counter)
{
hid_t child_gid;
int mpi_rank;
char gname[64];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
#ifdef BARRIER_CHECKS
if (!((counter + 1) % 10)) {
HDprintf("created %dth child groups\n", counter + 1);
MPI_Barrier(MPI_COMM_WORLD);
}
#endif /* BARRIER_CHECKS */
HDsnprintf(gname, sizeof(gname), "%dth_child_group", counter + 1);
child_gid = H5Gcreate2(gid, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((child_gid > 0), gname);
/* write datasets in parallel. */
write_dataset(memspace, filespace, gid);
if (counter < GROUP_DEPTH)
create_group_recursive(memspace, filespace, child_gid, counter + 1);
H5Gclose(child_gid);
}
/*
* This function is to verify the data from multiple group testing. It opens
* every dataset in every group and check their correctness.
*/
void
multiple_group_read(void)
{
int mpi_rank, mpi_size, error_num, size;
int m;
char gname[64];
hid_t plist, fid, gid, memspace, filespace;
hsize_t chunk_origin[DIM];
hsize_t chunk_dims[DIM], file_dims[DIM], count[DIM];
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
int ngroups;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
/* ngroups = pt->count; */ ngroups = NGROUPS;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, group, dataset, or attribute aren't supported with "
"this connector\n");
fflush(stdout);
}
return;
}
size = get_size();
plist = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
fid = H5Fopen(filename, H5F_ACC_RDONLY, plist);
H5Pclose(plist);
/* decide hyperslab for each process */
get_slab(chunk_origin, chunk_dims, count, file_dims, size);
/* select hyperslab for memory and file space */
memspace = H5Screate_simple(DIM, file_dims, NULL);
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
filespace = H5Screate_simple(DIM, file_dims, NULL);
H5Sselect_hyperslab(filespace, H5S_SELECT_SET, chunk_origin, chunk_dims, count, chunk_dims);
/* open every group under root group. */
for (m = 0; m < ngroups; m++) {
HDsnprintf(gname, sizeof(gname), "group%d", m);
gid = H5Gopen2(fid, gname, H5P_DEFAULT);
VRFY((gid > 0), gname);
/* check the data. */
if (m != 0)
if ((error_num = read_dataset(memspace, filespace, gid)) > 0)
nerrors += error_num;
/* check attribute.*/
error_num = 0;
if ((error_num = read_attribute(gid, is_group, m)) > 0)
nerrors += error_num;
H5Gclose(gid);
#ifdef BARRIER_CHECKS
if (!((m + 1) % 10))
MPI_Barrier(MPI_COMM_WORLD);
#endif /* BARRIER_CHECKS */
}
/* open all the groups in vertical direction. */
gid = H5Gopen2(fid, "group0", H5P_DEFAULT);
VRFY((gid > 0), "group0");
recursive_read_group(memspace, filespace, gid, 0);
H5Gclose(gid);
H5Sclose(filespace);
H5Sclose(memspace);
H5Fclose(fid);
}
/*
* This function opens all the datasets in a certain, checks the data using
* dataset_vrfy function.
*/
static int
read_dataset(hid_t memspace, hid_t filespace, hid_t gid)
{
int i, j, n, mpi_rank, mpi_size, size, attr_errors = 0, vrfy_errors = 0;
char dname[32];
DATATYPE *outdata = NULL, *indata = NULL;
hid_t did;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
size = get_size();
indata = (DATATYPE *)HDmalloc((size_t)size * (size_t)size * sizeof(DATATYPE));
VRFY((indata != NULL), "HDmalloc succeeded for indata");
outdata = (DATATYPE *)HDmalloc((size_t)size * (size_t)size * sizeof(DATATYPE));
VRFY((outdata != NULL), "HDmalloc succeeded for outdata");
for (n = 0; n < NDATASET; n++) {
HDsnprintf(dname, sizeof(dname), "dataset%d", n);
did = H5Dopen2(gid, dname, H5P_DEFAULT);
VRFY((did > 0), dname);
H5Dread(did, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, indata);
/* this is the original value */
for (i = 0; i < size; i++)
for (j = 0; j < size; j++) {
*outdata = n * 1000 + mpi_rank;
outdata++;
}
outdata -= size * size;
/* compare the original value(outdata) to the value in file(indata).*/
vrfy_errors = check_value(indata, outdata, size);
/* check attribute.*/
if ((attr_errors = read_attribute(did, is_dset, n)) > 0)
vrfy_errors += attr_errors;
H5Dclose(did);
}
HDfree(indata);
HDfree(outdata);
return vrfy_errors;
}
/*
* This recursive function opens all the groups in vertical direction and
* checks the data.
*/
static void
recursive_read_group(hid_t memspace, hid_t filespace, hid_t gid, int counter)
{
hid_t child_gid;
int mpi_rank, err_num = 0;
char gname[64];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
#ifdef BARRIER_CHECKS
if ((counter + 1) % 10)
MPI_Barrier(MPI_COMM_WORLD);
#endif /* BARRIER_CHECKS */
if ((err_num = read_dataset(memspace, filespace, gid)))
nerrors += err_num;
if (counter < GROUP_DEPTH) {
HDsnprintf(gname, sizeof(gname), "%dth_child_group", counter + 1);
child_gid = H5Gopen2(gid, gname, H5P_DEFAULT);
VRFY((child_gid > 0), gname);
recursive_read_group(memspace, filespace, child_gid, counter + 1);
H5Gclose(child_gid);
}
}
/* Create and write attribute for a group or a dataset. For groups, attribute
* is a scalar datum; for dataset, it is a one-dimensional array.
*/
static void
write_attribute(hid_t obj_id, int this_type, int num)
{
hid_t sid, aid;
hsize_t dspace_dims[1] = {8};
int i, mpi_rank, attr_data[8], dspace_rank = 1;
char attr_name[32];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if (this_type == is_group) {
HDsnprintf(attr_name, sizeof(attr_name), "Group Attribute %d", num);
sid = H5Screate(H5S_SCALAR);
aid = H5Acreate2(obj_id, attr_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT);
H5Awrite(aid, H5T_NATIVE_INT, &num);
H5Aclose(aid);
H5Sclose(sid);
} /* end if */
else if (this_type == is_dset) {
HDsnprintf(attr_name, sizeof(attr_name), "Dataset Attribute %d", num);
for (i = 0; i < 8; i++)
attr_data[i] = i;
sid = H5Screate_simple(dspace_rank, dspace_dims, NULL);
aid = H5Acreate2(obj_id, attr_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT);
H5Awrite(aid, H5T_NATIVE_INT, attr_data);
H5Aclose(aid);
H5Sclose(sid);
} /* end else-if */
}
/* Read and verify attribute for group or dataset. */
static int
read_attribute(hid_t obj_id, int this_type, int num)
{
hid_t aid;
hsize_t group_block[2] = {1, 1}, dset_block[2] = {1, 8};
int i, mpi_rank, in_num, in_data[8], out_data[8], vrfy_errors = 0;
char attr_name[32];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if (this_type == is_group) {
HDsnprintf(attr_name, sizeof(attr_name), "Group Attribute %d", num);
aid = H5Aopen(obj_id, attr_name, H5P_DEFAULT);
H5Aread(aid, H5T_NATIVE_INT, &in_num);
vrfy_errors = dataset_vrfy(NULL, NULL, NULL, group_block, &in_num, &num);
H5Aclose(aid);
}
else if (this_type == is_dset) {
HDsnprintf(attr_name, sizeof(attr_name), "Dataset Attribute %d", num);
for (i = 0; i < 8; i++)
out_data[i] = i;
aid = H5Aopen(obj_id, attr_name, H5P_DEFAULT);
H5Aread(aid, H5T_NATIVE_INT, in_data);
vrfy_errors = dataset_vrfy(NULL, NULL, NULL, dset_block, in_data, out_data);
H5Aclose(aid);
}
return vrfy_errors;
}
/* This functions compares the original data with the read-in data for its
* hyperslab part only by process ID.
*/
static int
check_value(DATATYPE *indata, DATATYPE *outdata, int size)
{
int mpi_rank, mpi_size, err_num = 0;
hsize_t i, j;
hsize_t chunk_origin[DIM];
hsize_t chunk_dims[DIM], count[DIM];
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
get_slab(chunk_origin, chunk_dims, count, NULL, size);
indata += chunk_origin[0] * (hsize_t)size;
outdata += chunk_origin[0] * (hsize_t)size;
for (i = chunk_origin[0]; i < (chunk_origin[0] + chunk_dims[0]); i++)
for (j = chunk_origin[1]; j < (chunk_origin[1] + chunk_dims[1]); j++) {
if (*indata != *outdata)
if (err_num++ < MAX_ERR_REPORT || VERBOSE_MED)
HDprintf("Dataset Verify failed at [%lu][%lu](row %lu, col%lu): expect %d, got %d\n",
(unsigned long)i, (unsigned long)j, (unsigned long)i, (unsigned long)j, *outdata,
*indata);
}
if (err_num > MAX_ERR_REPORT && !VERBOSE_MED)
HDprintf("[more errors ...]\n");
if (err_num)
HDprintf("%d errors found in check_value\n", err_num);
return err_num;
}
/* Decide the portion of data chunk in dataset by process ID.
*/
static void
get_slab(hsize_t chunk_origin[], hsize_t chunk_dims[], hsize_t count[], hsize_t file_dims[], int size)
{
int mpi_rank, mpi_size;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
if (chunk_origin != NULL) {
chunk_origin[0] = (hsize_t)mpi_rank * (hsize_t)(size / mpi_size);
chunk_origin[1] = 0;
}
if (chunk_dims != NULL) {
chunk_dims[0] = (hsize_t)(size / mpi_size);
chunk_dims[1] = (hsize_t)size;
}
if (file_dims != NULL)
file_dims[0] = file_dims[1] = (hsize_t)size;
if (count != NULL)
count[0] = count[1] = 1;
}
/*
* This function is based on bug demonstration code provided by Thomas
* Guignon(thomas.guignon@ifp.fr), and is intended to verify the
* correctness of my fix for that bug.
*
* In essence, the bug appeared when at least one process attempted to
* write a point selection -- for which collective I/O is not supported,
* and at least one other attempted to write some other type of selection
* for which collective I/O is supported.
*
* Since the processes did not compare notes before performing the I/O,
* some would attempt collective I/O while others performed independent
* I/O. A hang resulted.
*
* This function reproduces this situation. At present the test hangs
* on failure.
* JRM - 9/13/04
*/
#define N 4
void
io_mode_confusion(void)
{
/*
* HDF5 APIs definitions
*/
const int rank = 1;
const char *dataset_name = "IntArray";
hid_t file_id, dset_id; /* file and dataset identifiers */
hid_t filespace, memspace; /* file and memory dataspace */
/* identifiers */
hsize_t dimsf[1]; /* dataset dimensions */
int data[N] = {1}; /* pointer to data buffer to write */
hsize_t coord[N] = {0L, 1L, 2L, 3L};
hid_t plist_id; /* property list identifier */
herr_t status;
/*
* MPI variables
*/
int mpi_size, mpi_rank;
/*
* test bed related variables
*/
const char *fcn_name = "io_mode_confusion";
const hbool_t verbose = FALSE;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
#if 0
pt = GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
/*
* Set up file access property list with parallel I/O access
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Setting up property list.\n", mpi_rank, fcn_name);
plist_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((plist_id != -1), "H5Pcreate() failed");
status = H5Pset_fapl_mpio(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL);
VRFY((status >= 0), "H5Pset_fapl_mpio() failed");
/*
* Create a new file collectively and release property list identifier.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Creating new file.\n", mpi_rank, fcn_name);
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);
VRFY((file_id >= 0), "H5Fcreate() failed");
status = H5Pclose(plist_id);
VRFY((status >= 0), "H5Pclose() failed");
/*
* Create the dataspace for the dataset.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Creating the dataspace for the dataset.\n", mpi_rank, fcn_name);
dimsf[0] = N;
filespace = H5Screate_simple(rank, dimsf, NULL);
VRFY((filespace >= 0), "H5Screate_simple() failed.");
/*
* Create the dataset with default properties and close filespace.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Creating the dataset, and closing filespace.\n", mpi_rank, fcn_name);
dset_id =
H5Dcreate2(file_id, dataset_name, H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2() failed");
status = H5Sclose(filespace);
VRFY((status >= 0), "H5Sclose() failed");
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Screate_simple().\n", mpi_rank, fcn_name);
memspace = H5Screate_simple(rank, dimsf, NULL);
VRFY((memspace >= 0), "H5Screate_simple() failed.");
if (mpi_rank == 0) {
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Sselect_all(memspace).\n", mpi_rank, fcn_name);
status = H5Sselect_all(memspace);
VRFY((status >= 0), "H5Sselect_all() failed");
}
else {
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Sselect_none(memspace).\n", mpi_rank, fcn_name);
status = H5Sselect_none(memspace);
VRFY((status >= 0), "H5Sselect_none() failed");
}
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling MPI_Barrier().\n", mpi_rank, fcn_name);
MPI_Barrier(MPI_COMM_WORLD);
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Dget_space().\n", mpi_rank, fcn_name);
filespace = H5Dget_space(dset_id);
VRFY((filespace >= 0), "H5Dget_space() failed");
/* select all */
if (mpi_rank == 0) {
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Sselect_elements() -- set up hang?\n", mpi_rank, fcn_name);
status = H5Sselect_elements(filespace, H5S_SELECT_SET, N, (const hsize_t *)&coord);
VRFY((status >= 0), "H5Sselect_elements() failed");
}
else { /* select nothing */
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Sselect_none().\n", mpi_rank, fcn_name);
status = H5Sselect_none(filespace);
VRFY((status >= 0), "H5Sselect_none() failed");
}
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling MPI_Barrier().\n", mpi_rank, fcn_name);
MPI_Barrier(MPI_COMM_WORLD);
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Pcreate().\n", mpi_rank, fcn_name);
plist_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((plist_id != -1), "H5Pcreate() failed");
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Pset_dxpl_mpio().\n", mpi_rank, fcn_name);
status = H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
VRFY((status >= 0), "H5Pset_dxpl_mpio() failed");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
status = H5Pset_dxpl_mpio_collective_opt(plist_id, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((status >= 0), "set independent IO collectively succeeded");
}
if (verbose)
HDfprintf(stdout, "%0d:%s: Calling H5Dwrite() -- hang here?.\n", mpi_rank, fcn_name);
status = H5Dwrite(dset_id, H5T_NATIVE_INT, memspace, filespace, plist_id, data);
if (verbose)
HDfprintf(stdout, "%0d:%s: Returned from H5Dwrite(), status=%d.\n", mpi_rank, fcn_name, status);
VRFY((status >= 0), "H5Dwrite() failed");
/*
* Close/release resources.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Cleaning up from test.\n", mpi_rank, fcn_name);
status = H5Dclose(dset_id);
VRFY((status >= 0), "H5Dclose() failed");
status = H5Sclose(filespace);
VRFY((status >= 0), "H5Dclose() failed");
status = H5Sclose(memspace);
VRFY((status >= 0), "H5Sclose() failed");
status = H5Pclose(plist_id);
VRFY((status >= 0), "H5Pclose() failed");
status = H5Fclose(file_id);
VRFY((status >= 0), "H5Fclose() failed");
if (verbose)
HDfprintf(stdout, "%0d:%s: Done.\n", mpi_rank, fcn_name);
return;
} /* io_mode_confusion() */
#undef N
/*
* At present, the object header code maintains an image of its on disk
* representation, which is updates as necessary instead of generating on
* request.
*
* Prior to the fix that this test in designed to verify, the image of the
* on disk representation was only updated on flush -- not when the object
* header was marked clean.
*
* This worked perfectly well as long as all writes of a given object
* header were written from a single process. However, with the implementation
* of round robin metadata data writes in parallel HDF5, this is no longer
* the case -- it is possible for a given object header to be flushed from
* several different processes, with the object header simply being marked
* clean in all other processes on each flush. This resulted in NULL or
* out of data object header information being written to disk.
*
* To repair this, I modified the object header code to update its
* on disk image both on flush on when marked clean.
*
* This test is directed at verifying that the fix performs as expected.
*
* The test functions by creating a HDF5 file with several small datasets,
* and then flushing the file. This should result of at least one of
* the associated object headers being flushed by a process other than
* process 0.
*
* Then for each data set, add an attribute and flush the file again.
*
* Close the file and re-open it.
*
* Open the each of the data sets in turn. If all opens are successful,
* the test passes. Otherwise the test fails.
*
* Note that this test will probably become irrelevant shortly, when we
* land the journaling modifications on the trunk -- at which point all
* cache clients will have to construct on disk images on demand.
*
* JRM -- 10/13/10
*/
#define NUM_DATA_SETS 4
#define LOCAL_DATA_SIZE 4
#define LARGE_ATTR_SIZE 256
/* Since all even and odd processes are split into writer and reader comm
* respectively, process 0 and 1 in COMM_WORLD become the root process of
* the writer and reader comm respectively.
*/
#define Writer_Root 0
#define Reader_Root 1
#define Reader_wait(mpi_err, xsteps) mpi_err = MPI_Bcast(&xsteps, 1, MPI_INT, Writer_Root, MPI_COMM_WORLD)
#define Reader_result(mpi_err, xsteps_done) \
mpi_err = MPI_Bcast(&xsteps_done, 1, MPI_INT, Reader_Root, MPI_COMM_WORLD)
#define Reader_check(mpi_err, xsteps, xsteps_done) \
{ \
Reader_wait(mpi_err, xsteps); \
Reader_result(mpi_err, xsteps_done); \
}
/* object names used by both rr_obj_hdr_flush_confusion and
* rr_obj_hdr_flush_confusion_reader.
*/
const char *dataset_name[NUM_DATA_SETS] = {"dataset_0", "dataset_1", "dataset_2", "dataset_3"};
const char *att_name[NUM_DATA_SETS] = {"attribute_0", "attribute_1", "attribute_2", "attribute_3"};
const char *lg_att_name[NUM_DATA_SETS] = {"large_attribute_0", "large_attribute_1", "large_attribute_2",
"large_attribute_3"};
void
rr_obj_hdr_flush_confusion(void)
{
/* MPI variables */
/* private communicator size and rank */
int mpi_size;
int mpi_rank;
int mrc; /* mpi error code */
int is_reader; /* 1 for reader process; 0 for writer process. */
MPI_Comm comm;
/* test bed related variables */
const char *fcn_name = "rr_obj_hdr_flush_confusion";
const hbool_t verbose = FALSE;
/* Create two new private communicators from MPI_COMM_WORLD.
* Even and odd ranked processes go to comm_writers and comm_readers
* respectively.
*/
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file, dataset, attribute, dataset more, attribute more, or "
"file flush aren't supported with this connector\n");
fflush(stdout);
}
return;
}
HDassert(mpi_size > 2);
is_reader = mpi_rank % 2;
mrc = MPI_Comm_split(MPI_COMM_WORLD, is_reader, mpi_rank, &comm);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_split");
/* The reader processes branches off to do reading
* while the writer processes continues to do writing
* Whenever writers finish one writing step, including a H5Fflush,
* they inform the readers, via MPI_COMM_WORLD, to verify.
* They will wait for the result from the readers before doing the next
* step. When all steps are done, they inform readers to end.
*/
if (is_reader)
rr_obj_hdr_flush_confusion_reader(comm);
else
rr_obj_hdr_flush_confusion_writer(comm);
MPI_Comm_free(&comm);
if (verbose)
HDfprintf(stdout, "%0d:%s: Done.\n", mpi_rank, fcn_name);
return;
} /* rr_obj_hdr_flush_confusion() */
void
rr_obj_hdr_flush_confusion_writer(MPI_Comm comm)
{
int i;
int j;
hid_t file_id = -1;
hid_t fapl_id = -1;
hid_t dxpl_id = -1;
hid_t att_id[NUM_DATA_SETS];
hid_t att_space[NUM_DATA_SETS];
hid_t lg_att_id[NUM_DATA_SETS];
hid_t lg_att_space[NUM_DATA_SETS];
hid_t disk_space[NUM_DATA_SETS];
hid_t mem_space[NUM_DATA_SETS];
hid_t dataset[NUM_DATA_SETS];
hsize_t att_size[1];
hsize_t lg_att_size[1];
hsize_t disk_count[1];
hsize_t disk_size[1];
hsize_t disk_start[1];
hsize_t mem_count[1];
hsize_t mem_size[1];
hsize_t mem_start[1];
herr_t err;
double data[LOCAL_DATA_SIZE];
double att[LOCAL_DATA_SIZE];
double lg_att[LARGE_ATTR_SIZE];
/* MPI variables */
/* world communication size and rank */
int mpi_world_size;
int mpi_world_rank;
/* private communicator size and rank */
int mpi_size;
int mpi_rank;
int mrc; /* mpi error code */
/* steps to verify and have been verified */
int steps = 0;
int steps_done = 0;
/* test bed related variables */
const char *fcn_name = "rr_obj_hdr_flush_confusion_writer";
const hbool_t verbose = FALSE;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
/*
* setup test bed related variables:
*/
#if 0
pt = (const H5Ptest_param_t *)GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_world_size);
MPI_Comm_rank(comm, &mpi_rank);
MPI_Comm_size(comm, &mpi_size);
/*
* Set up file access property list with parallel I/O access
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Setting up property list.\n", mpi_rank, fcn_name);
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id != -1), "H5Pcreate(H5P_FILE_ACCESS) failed");
err = H5Pset_fapl_mpio(fapl_id, comm, MPI_INFO_NULL);
VRFY((err >= 0), "H5Pset_fapl_mpio() failed");
/*
* Create a new file collectively and release property list identifier.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Creating new file \"%s\".\n", mpi_rank, fcn_name, filename);
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate() failed");
err = H5Pclose(fapl_id);
VRFY((err >= 0), "H5Pclose(fapl_id) failed");
/*
* Step 1: create the data sets and write data.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Creating the datasets.\n", mpi_rank, fcn_name);
disk_size[0] = (hsize_t)(LOCAL_DATA_SIZE * mpi_size);
mem_size[0] = (hsize_t)(LOCAL_DATA_SIZE);
for (i = 0; i < NUM_DATA_SETS; i++) {
disk_space[i] = H5Screate_simple(1, disk_size, NULL);
VRFY((disk_space[i] >= 0), "H5Screate_simple(1) failed.\n");
dataset[i] = H5Dcreate2(file_id, dataset_name[i], H5T_NATIVE_DOUBLE, disk_space[i], H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT);
VRFY((dataset[i] >= 0), "H5Dcreate(1) failed.\n");
}
/*
* setup data transfer property list
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Setting up dxpl.\n", mpi_rank, fcn_name);
dxpl_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_id != -1), "H5Pcreate(H5P_DATASET_XFER) failed.\n");
err = H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE);
VRFY((err >= 0), "H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) failed.\n");
/*
* write data to the data sets
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Writing datasets.\n", mpi_rank, fcn_name);
disk_count[0] = (hsize_t)(LOCAL_DATA_SIZE);
disk_start[0] = (hsize_t)(LOCAL_DATA_SIZE * mpi_rank);
mem_count[0] = (hsize_t)(LOCAL_DATA_SIZE);
mem_start[0] = (hsize_t)(0);
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
data[j] = (double)(mpi_rank + 1);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sselect_hyperslab(disk_space[i], H5S_SELECT_SET, disk_start, NULL, disk_count, NULL);
VRFY((err >= 0), "H5Sselect_hyperslab(1) failed.\n");
mem_space[i] = H5Screate_simple(1, mem_size, NULL);
VRFY((mem_space[i] >= 0), "H5Screate_simple(2) failed.\n");
err = H5Sselect_hyperslab(mem_space[i], H5S_SELECT_SET, mem_start, NULL, mem_count, NULL);
VRFY((err >= 0), "H5Sselect_hyperslab(2) failed.\n");
err = H5Dwrite(dataset[i], H5T_NATIVE_DOUBLE, mem_space[i], disk_space[i], dxpl_id, data);
VRFY((err >= 0), "H5Dwrite(1) failed.\n");
for (j = 0; j < LOCAL_DATA_SIZE; j++)
data[j] *= 10.0;
}
/*
* close the data spaces
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing dataspaces.\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sclose(disk_space[i]);
VRFY((err >= 0), "H5Sclose(disk_space[i]) failed.\n");
err = H5Sclose(mem_space[i]);
VRFY((err >= 0), "H5Sclose(mem_space[i]) failed.\n");
}
/* End of Step 1: create the data sets and write data. */
/*
* flush the metadata cache
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: flushing metadata cache.\n", mpi_rank, fcn_name);
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "H5Fflush(1) failed.\n");
/* Tell the reader to check the file up to steps. */
steps++;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
/*
* Step 2: write attributes to each dataset
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: writing attributes.\n", mpi_rank, fcn_name);
att_size[0] = (hsize_t)(LOCAL_DATA_SIZE);
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
att[j] = (double)(j + 1);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
att_space[i] = H5Screate_simple(1, att_size, NULL);
VRFY((att_space[i] >= 0), "H5Screate_simple(3) failed.\n");
att_id[i] =
H5Acreate2(dataset[i], att_name[i], H5T_NATIVE_DOUBLE, att_space[i], H5P_DEFAULT, H5P_DEFAULT);
VRFY((att_id[i] >= 0), "H5Acreate(1) failed.\n");
err = H5Awrite(att_id[i], H5T_NATIVE_DOUBLE, att);
VRFY((err >= 0), "H5Awrite(1) failed.\n");
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
att[j] /= 10.0;
}
}
/*
* close attribute IDs and spaces
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing attr ids and spaces .\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sclose(att_space[i]);
VRFY((err >= 0), "H5Sclose(att_space[i]) failed.\n");
err = H5Aclose(att_id[i]);
VRFY((err >= 0), "H5Aclose(att_id[i]) failed.\n");
}
/* End of Step 2: write attributes to each dataset */
/*
* flush the metadata cache again
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: flushing metadata cache.\n", mpi_rank, fcn_name);
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "H5Fflush(2) failed.\n");
/* Tell the reader to check the file up to steps. */
steps++;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
/*
* Step 3: write large attributes to each dataset
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: writing large attributes.\n", mpi_rank, fcn_name);
lg_att_size[0] = (hsize_t)(LARGE_ATTR_SIZE);
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] = (double)(j + 1);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
lg_att_space[i] = H5Screate_simple(1, lg_att_size, NULL);
VRFY((lg_att_space[i] >= 0), "H5Screate_simple(4) failed.\n");
lg_att_id[i] = H5Acreate2(dataset[i], lg_att_name[i], H5T_NATIVE_DOUBLE, lg_att_space[i], H5P_DEFAULT,
H5P_DEFAULT);
VRFY((lg_att_id[i] >= 0), "H5Acreate(2) failed.\n");
err = H5Awrite(lg_att_id[i], H5T_NATIVE_DOUBLE, lg_att);
VRFY((err >= 0), "H5Awrite(2) failed.\n");
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] /= 10.0;
}
}
/* Step 3: write large attributes to each dataset */
/*
* flush the metadata cache yet again to clean the object headers.
*
* This is an attempt to create a situation where we have dirty
* object header continuation chunks, but clean object headers
* to verify a speculative bug fix -- it doesn't seem to work,
* but I will leave the code in anyway, as the object header
* code is going to change a lot in the near future.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: flushing metadata cache.\n", mpi_rank, fcn_name);
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "H5Fflush(3) failed.\n");
/* Tell the reader to check the file up to steps. */
steps++;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
/*
* Step 4: write different large attributes to each dataset
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: writing different large attributes.\n", mpi_rank, fcn_name);
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] = (double)(j + 2);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Awrite(lg_att_id[i], H5T_NATIVE_DOUBLE, lg_att);
VRFY((err >= 0), "H5Awrite(2) failed.\n");
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] /= 10.0;
}
}
/* End of Step 4: write different large attributes to each dataset */
/*
* flush the metadata cache again
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: flushing metadata cache.\n", mpi_rank, fcn_name);
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
VRFY((err >= 0), "H5Fflush(3) failed.\n");
/* Tell the reader to check the file up to steps. */
steps++;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
/* Step 5: Close all objects and the file */
/*
* close large attribute IDs and spaces
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing large attr ids and spaces .\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sclose(lg_att_space[i]);
VRFY((err >= 0), "H5Sclose(lg_att_space[i]) failed.\n");
err = H5Aclose(lg_att_id[i]);
VRFY((err >= 0), "H5Aclose(lg_att_id[i]) failed.\n");
}
/*
* close the data sets
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing datasets .\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Dclose(dataset[i]);
VRFY((err >= 0), "H5Dclose(dataset[i])1 failed.\n");
}
/*
* close the data transfer property list.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing dxpl .\n", mpi_rank, fcn_name);
err = H5Pclose(dxpl_id);
VRFY((err >= 0), "H5Pclose(dxpl_id) failed.\n");
/*
* Close file.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing file.\n", mpi_rank, fcn_name);
err = H5Fclose(file_id);
VRFY((err >= 0), "H5Fclose(1) failed");
/* End of Step 5: Close all objects and the file */
/* Tell the reader to check the file up to steps. */
steps++;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
/* All done. Inform reader to end. */
steps = 0;
Reader_check(mrc, steps, steps_done);
VRFY((MPI_SUCCESS == mrc), "Reader_check failed");
if (verbose)
HDfprintf(stdout, "%0d:%s: Done.\n", mpi_rank, fcn_name);
return;
} /* rr_obj_hdr_flush_confusion_writer() */
void
rr_obj_hdr_flush_confusion_reader(MPI_Comm comm)
{
int i;
int j;
hid_t file_id = -1;
hid_t fapl_id = -1;
hid_t dxpl_id = -1;
hid_t lg_att_id[NUM_DATA_SETS];
hid_t lg_att_type[NUM_DATA_SETS];
hid_t disk_space[NUM_DATA_SETS];
hid_t mem_space[NUM_DATA_SETS];
hid_t dataset[NUM_DATA_SETS];
hsize_t disk_count[1];
hsize_t disk_start[1];
hsize_t mem_count[1];
hsize_t mem_size[1];
hsize_t mem_start[1];
herr_t err;
htri_t tri_err;
double data[LOCAL_DATA_SIZE];
double data_read[LOCAL_DATA_SIZE];
double att[LOCAL_DATA_SIZE];
double att_read[LOCAL_DATA_SIZE];
double lg_att[LARGE_ATTR_SIZE];
double lg_att_read[LARGE_ATTR_SIZE];
/* MPI variables */
/* world communication size and rank */
int mpi_world_size;
int mpi_world_rank;
/* private communicator size and rank */
int mpi_size;
int mpi_rank;
int mrc; /* mpi error code */
int steps = -1; /* How far (steps) to verify the file */
int steps_done = -1; /* How far (steps) have been verified */
/* test bed related variables */
const char *fcn_name = "rr_obj_hdr_flush_confusion_reader";
const hbool_t verbose = FALSE;
#if 0
const H5Ptest_param_t *pt;
#endif
char *filename;
/*
* setup test bed related variables:
*/
#if 0
pt = (const H5Ptest_param_t *)GetTestParameters();
#endif
/* filename = pt->name; */ filename = PARATESTFILE;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_world_size);
MPI_Comm_rank(comm, &mpi_rank);
MPI_Comm_size(comm, &mpi_size);
/* Repeatedly re-open the file and verify its contents until it is */
/* told to end (when steps=0). */
while (steps_done != 0) {
Reader_wait(mrc, steps);
VRFY((mrc >= 0), "Reader_wait failed");
steps_done = 0;
if (steps > 0) {
/*
* Set up file access property list with parallel I/O access
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Setting up property list.\n", mpi_rank, fcn_name);
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl_id != -1), "H5Pcreate(H5P_FILE_ACCESS) failed");
err = H5Pset_fapl_mpio(fapl_id, comm, MPI_INFO_NULL);
VRFY((err >= 0), "H5Pset_fapl_mpio() failed");
/*
* Create a new file collectively and release property list identifier.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Re-open file \"%s\".\n", mpi_rank, fcn_name, filename);
file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl_id);
VRFY((file_id >= 0), "H5Fopen() failed");
err = H5Pclose(fapl_id);
VRFY((err >= 0), "H5Pclose(fapl_id) failed");
#if 1
if (steps >= 1) {
/*=====================================================*
* Step 1: open the data sets and read data.
*=====================================================*/
if (verbose)
HDfprintf(stdout, "%0d:%s: opening the datasets.\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
dataset[i] = -1;
}
for (i = 0; i < NUM_DATA_SETS; i++) {
dataset[i] = H5Dopen2(file_id, dataset_name[i], H5P_DEFAULT);
VRFY((dataset[i] >= 0), "H5Dopen(1) failed.\n");
disk_space[i] = H5Dget_space(dataset[i]);
VRFY((disk_space[i] >= 0), "H5Dget_space failed.\n");
}
/*
* setup data transfer property list
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Setting up dxpl.\n", mpi_rank, fcn_name);
dxpl_id = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl_id != -1), "H5Pcreate(H5P_DATASET_XFER) failed.\n");
err = H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE);
VRFY((err >= 0), "H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) failed.\n");
/*
* read data from the data sets
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: Reading datasets.\n", mpi_rank, fcn_name);
disk_count[0] = (hsize_t)(LOCAL_DATA_SIZE);
disk_start[0] = (hsize_t)(LOCAL_DATA_SIZE * mpi_rank);
mem_size[0] = (hsize_t)(LOCAL_DATA_SIZE);
mem_count[0] = (hsize_t)(LOCAL_DATA_SIZE);
mem_start[0] = (hsize_t)(0);
/* set up expected data for verification */
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
data[j] = (double)(mpi_rank + 1);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sselect_hyperslab(disk_space[i], H5S_SELECT_SET, disk_start, NULL, disk_count,
NULL);
VRFY((err >= 0), "H5Sselect_hyperslab(1) failed.\n");
mem_space[i] = H5Screate_simple(1, mem_size, NULL);
VRFY((mem_space[i] >= 0), "H5Screate_simple(2) failed.\n");
err = H5Sselect_hyperslab(mem_space[i], H5S_SELECT_SET, mem_start, NULL, mem_count, NULL);
VRFY((err >= 0), "H5Sselect_hyperslab(2) failed.\n");
err = H5Dread(dataset[i], H5T_NATIVE_DOUBLE, mem_space[i], disk_space[i], dxpl_id,
data_read);
VRFY((err >= 0), "H5Dread(1) failed.\n");
/* compare read data with expected data */
for (j = 0; j < LOCAL_DATA_SIZE; j++)
if (!H5_DBL_ABS_EQUAL(data_read[j], data[j])) {
HDfprintf(stdout,
"%0d:%s: Reading datasets value failed in "
"Dataset %d, at position %d: expect %f, got %f.\n",
mpi_rank, fcn_name, i, j, data[j], data_read[j]);
nerrors++;
}
for (j = 0; j < LOCAL_DATA_SIZE; j++)
data[j] *= 10.0;
}
/*
* close the data spaces
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing dataspaces.\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
err = H5Sclose(disk_space[i]);
VRFY((err >= 0), "H5Sclose(disk_space[i]) failed.\n");
err = H5Sclose(mem_space[i]);
VRFY((err >= 0), "H5Sclose(mem_space[i]) failed.\n");
}
steps_done++;
}
/* End of Step 1: open the data sets and read data. */
#endif
#if 1
/*=====================================================*
* Step 2: reading attributes from each dataset
*=====================================================*/
if (steps >= 2) {
if (verbose)
HDfprintf(stdout, "%0d:%s: reading attributes.\n", mpi_rank, fcn_name);
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
att[j] = (double)(j + 1);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
hid_t att_id, att_type;
att_id = H5Aopen(dataset[i], att_name[i], H5P_DEFAULT);
VRFY((att_id >= 0), "H5Aopen failed.\n");
att_type = H5Aget_type(att_id);
VRFY((att_type >= 0), "H5Aget_type failed.\n");
tri_err = H5Tequal(att_type, H5T_NATIVE_DOUBLE);
VRFY((tri_err >= 0), "H5Tequal failed.\n");
if (tri_err == 0) {
HDfprintf(stdout, "%0d:%s: Mismatched Attribute type of Dataset %d.\n", mpi_rank,
fcn_name, i);
nerrors++;
}
else {
/* should verify attribute size before H5Aread */
err = H5Aread(att_id, H5T_NATIVE_DOUBLE, att_read);
VRFY((err >= 0), "H5Aread failed.\n");
/* compare read attribute data with expected data */
for (j = 0; j < LOCAL_DATA_SIZE; j++)
if (!H5_DBL_ABS_EQUAL(att_read[j], att[j])) {
HDfprintf(stdout,
"%0d:%s: Mismatched attribute data read in Dataset %d, at position "
"%d: expect %f, got %f.\n",
mpi_rank, fcn_name, i, j, att[j], att_read[j]);
nerrors++;
}
for (j = 0; j < LOCAL_DATA_SIZE; j++) {
att[j] /= 10.0;
}
}
err = H5Aclose(att_id);
VRFY((err >= 0), "H5Aclose failed.\n");
}
steps_done++;
}
/* End of Step 2: reading attributes from each dataset */
#endif
#if 1
/*=====================================================*
* Step 3 or 4: read large attributes from each dataset.
* Step 4 has different attribute value from step 3.
*=====================================================*/
if (steps >= 3) {
if (verbose)
HDfprintf(stdout, "%0d:%s: reading large attributes.\n", mpi_rank, fcn_name);
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] = (steps == 3) ? (double)(j + 1) : (double)(j + 2);
}
for (i = 0; i < NUM_DATA_SETS; i++) {
lg_att_id[i] = H5Aopen(dataset[i], lg_att_name[i], H5P_DEFAULT);
VRFY((lg_att_id[i] >= 0), "H5Aopen(2) failed.\n");
lg_att_type[i] = H5Aget_type(lg_att_id[i]);
VRFY((err >= 0), "H5Aget_type failed.\n");
tri_err = H5Tequal(lg_att_type[i], H5T_NATIVE_DOUBLE);
VRFY((tri_err >= 0), "H5Tequal failed.\n");
if (tri_err == 0) {
HDfprintf(stdout, "%0d:%s: Mismatched Large attribute type of Dataset %d.\n",
mpi_rank, fcn_name, i);
nerrors++;
}
else {
/* should verify large attribute size before H5Aread */
err = H5Aread(lg_att_id[i], H5T_NATIVE_DOUBLE, lg_att_read);
VRFY((err >= 0), "H5Aread failed.\n");
/* compare read attribute data with expected data */
for (j = 0; j < LARGE_ATTR_SIZE; j++)
if (!H5_DBL_ABS_EQUAL(lg_att_read[j], lg_att[j])) {
HDfprintf(stdout,
"%0d:%s: Mismatched large attribute data read in Dataset %d, at "
"position %d: expect %f, got %f.\n",
mpi_rank, fcn_name, i, j, lg_att[j], lg_att_read[j]);
nerrors++;
}
for (j = 0; j < LARGE_ATTR_SIZE; j++) {
lg_att[j] /= 10.0;
}
}
err = H5Tclose(lg_att_type[i]);
VRFY((err >= 0), "H5Tclose failed.\n");
err = H5Aclose(lg_att_id[i]);
VRFY((err >= 0), "H5Aclose failed.\n");
}
/* Both step 3 and 4 use this same read checking code. */
steps_done = (steps == 3) ? 3 : 4;
}
/* End of Step 3 or 4: read large attributes from each dataset */
#endif
/*=====================================================*
* Step 5: read all objects from the file
*=====================================================*/
if (steps >= 5) {
/* nothing extra to verify. The file is closed normally. */
/* Just increment steps_done */
steps_done++;
}
/*
* Close the data sets
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing datasets again.\n", mpi_rank, fcn_name);
for (i = 0; i < NUM_DATA_SETS; i++) {
if (dataset[i] >= 0) {
err = H5Dclose(dataset[i]);
VRFY((err >= 0), "H5Dclose(dataset[i])1 failed.\n");
}
}
/*
* close the data transfer property list.
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing dxpl .\n", mpi_rank, fcn_name);
err = H5Pclose(dxpl_id);
VRFY((err >= 0), "H5Pclose(dxpl_id) failed.\n");
/*
* Close the file
*/
if (verbose)
HDfprintf(stdout, "%0d:%s: closing file again.\n", mpi_rank, fcn_name);
err = H5Fclose(file_id);
VRFY((err >= 0), "H5Fclose(1) failed");
} /* else if (steps_done==0) */
Reader_result(mrc, steps_done);
} /* end while(1) */
if (verbose)
HDfprintf(stdout, "%0d:%s: Done.\n", mpi_rank, fcn_name);
return;
} /* rr_obj_hdr_flush_confusion_reader() */
#undef NUM_DATA_SETS
#undef LOCAL_DATA_SIZE
#undef LARGE_ATTR_SIZE
#undef Reader_check
#undef Reader_wait
#undef Reader_result
#undef Writer_Root
#undef Reader_Root
/*
* Test creating a chunked dataset in parallel in a file with an alignment set
* and an alignment threshold large enough to avoid aligning the chunks but
* small enough that the raw data aggregator will be aligned if it is treated as
* an object that must be aligned by the library
*/
#define CHUNK_SIZE 72
#define NCHUNKS 32
#define AGGR_SIZE 2048
#define EXTRA_ALIGN 100
void
chunk_align_bug_1(void)
{
int mpi_rank;
hid_t file_id, dset_id, fapl_id, dcpl_id, space_id;
hsize_t dims = CHUNK_SIZE * NCHUNKS, cdims = CHUNK_SIZE;
#if 0
h5_stat_size_t file_size;
hsize_t align;
#endif
herr_t ret;
const char *filename;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
/* Create file without alignment */
fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type);
VRFY((fapl_id >= 0), "create_faccess_plist succeeded");
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
VRFY((file_id >= 0), "H5Fcreate succeeded");
/* Close file */
ret = H5Fclose(file_id);
VRFY((ret >= 0), "H5Fclose succeeded");
#if 0
/* Get file size */
file_size = h5_get_file_size(filename, fapl_id);
VRFY((file_size >= 0), "h5_get_file_size succeeded");
/* Calculate alignment value, set to allow a chunk to squeak in between the
* original EOF and the aligned location of the aggregator. Add some space
* for the dataset metadata */
align = (hsize_t)file_size + CHUNK_SIZE + EXTRA_ALIGN;
#endif
/* Set aggregator size and alignment, disable metadata aggregator */
HDassert(AGGR_SIZE > CHUNK_SIZE);
ret = H5Pset_small_data_block_size(fapl_id, AGGR_SIZE);
VRFY((ret >= 0), "H5Pset_small_data_block_size succeeded");
ret = H5Pset_meta_block_size(fapl_id, 0);
VRFY((ret >= 0), "H5Pset_meta_block_size succeeded");
#if 0
ret = H5Pset_alignment(fapl_id, CHUNK_SIZE + 1, align);
VRFY((ret >= 0), "H5Pset_small_data_block_size succeeded");
#endif
/* Reopen file with new settings */
file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id);
VRFY((file_id >= 0), "H5Fopen succeeded");
/* Create dataset */
space_id = H5Screate_simple(1, &dims, NULL);
VRFY((space_id >= 0), "H5Screate_simple succeeded");
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl_id >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dcpl_id, 1, &cdims);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_CHAR, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2 succeeded");
/* Close ids */
ret = H5Dclose(dset_id);
VRFY((dset_id >= 0), "H5Dclose succeeded");
ret = H5Sclose(space_id);
VRFY((space_id >= 0), "H5Sclose succeeded");
ret = H5Pclose(dcpl_id);
VRFY((dcpl_id >= 0), "H5Pclose succeeded");
ret = H5Pclose(fapl_id);
VRFY((fapl_id >= 0), "H5Pclose succeeded");
/* Close file */
ret = H5Fclose(file_id);
VRFY((ret >= 0), "H5Fclose succeeded");
return;
} /* end chunk_align_bug_1() */
/*=============================================================================
* End of t_mdset.c
*===========================================================================*/
+192
View File
@@ -0,0 +1,192 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Test parallel HDF5 basic components
*/
#include "hdf5.h"
#include "testphdf5.h"
/*-------------------------------------------------------------------------
* Function: test_fapl_mpio_dup
*
* Purpose: Test if fapl_mpio property list keeps a duplicate of the
* communicator and INFO objects given when set; and returns
* duplicates of its components when H5Pget_fapl_mpio is called.
*
* Return: Success: None
* Failure: Abort
*
* Programmer: Albert Cheng
* January 9, 2003
*
*-------------------------------------------------------------------------
*/
void
test_fapl_mpio_dup(void)
{
int mpi_size, mpi_rank;
MPI_Comm comm, comm_tmp;
int mpi_size_old, mpi_rank_old;
int mpi_size_tmp, mpi_rank_tmp;
MPI_Info info = MPI_INFO_NULL;
MPI_Info info_tmp = MPI_INFO_NULL;
int mrc; /* MPI return value */
hid_t acc_pl; /* File access properties */
herr_t ret; /* HDF5 return value */
int nkeys, nkeys_tmp;
if (VERBOSE_MED)
HDprintf("Verify fapl_mpio duplicates communicator and INFO objects\n");
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if (VERBOSE_MED)
HDprintf("rank/size of MPI_COMM_WORLD are %d/%d\n", mpi_rank, mpi_size);
/* Create a new communicator that has the same processes as MPI_COMM_WORLD.
* Use MPI_Comm_split because it is simpler than MPI_Comm_create
*/
mrc = MPI_Comm_split(MPI_COMM_WORLD, 0, 0, &comm);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_split");
MPI_Comm_size(comm, &mpi_size_old);
MPI_Comm_rank(comm, &mpi_rank_old);
if (VERBOSE_MED)
HDprintf("rank/size of comm are %d/%d\n", mpi_rank_old, mpi_size_old);
/* create a new INFO object with some trivial information. */
mrc = MPI_Info_create(&info);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_create");
mrc = MPI_Info_set(info, "hdf_info_name", "XYZ");
VRFY((mrc == MPI_SUCCESS), "MPI_Info_set");
if (MPI_INFO_NULL != info) {
mrc = MPI_Info_get_nkeys(info, &nkeys);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_get_nkeys");
}
#if 0
if (VERBOSE_MED)
h5_dump_info_object(info);
#endif
acc_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((acc_pl >= 0), "H5P_FILE_ACCESS");
ret = H5Pset_fapl_mpio(acc_pl, comm, info);
VRFY((ret >= 0), "");
/* Case 1:
* Free the created communicator and INFO object.
* Check if the access property list is still valid and can return
* valid communicator and INFO object.
*/
mrc = MPI_Comm_free(&comm);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free");
if (MPI_INFO_NULL != info) {
mrc = MPI_Info_free(&info);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_free");
}
ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp);
VRFY((ret >= 0), "H5Pget_fapl_mpio");
MPI_Comm_size(comm_tmp, &mpi_size_tmp);
MPI_Comm_rank(comm_tmp, &mpi_rank_tmp);
if (VERBOSE_MED)
HDprintf("After H5Pget_fapl_mpio: rank/size of comm are %d/%d\n", mpi_rank_tmp, mpi_size_tmp);
VRFY((mpi_size_tmp == mpi_size), "MPI_Comm_size");
VRFY((mpi_rank_tmp == mpi_rank), "MPI_Comm_rank");
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_get_nkeys");
VRFY((nkeys_tmp == nkeys), "new and old nkeys equal");
}
#if 0
if (VERBOSE_MED)
h5_dump_info_object(info_tmp);
#endif
/* Case 2:
* Free the retrieved communicator and INFO object.
* Check if the access property list is still valid and can return
* valid communicator and INFO object.
* Also verify the NULL argument option.
*/
mrc = MPI_Comm_free(&comm_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free");
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_free(&info_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_free");
}
/* check NULL argument options. */
ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, NULL);
VRFY((ret >= 0), "H5Pget_fapl_mpio Comm only");
mrc = MPI_Comm_free(&comm_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free");
ret = H5Pget_fapl_mpio(acc_pl, NULL, &info_tmp);
VRFY((ret >= 0), "H5Pget_fapl_mpio Info only");
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_free(&info_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_free");
}
ret = H5Pget_fapl_mpio(acc_pl, NULL, NULL);
VRFY((ret >= 0), "H5Pget_fapl_mpio neither");
/* now get both and check validity too. */
/* Do not free the returned objects which are used in the next case. */
ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp);
VRFY((ret >= 0), "H5Pget_fapl_mpio");
MPI_Comm_size(comm_tmp, &mpi_size_tmp);
MPI_Comm_rank(comm_tmp, &mpi_rank_tmp);
if (VERBOSE_MED)
HDprintf("After second H5Pget_fapl_mpio: rank/size of comm are %d/%d\n", mpi_rank_tmp, mpi_size_tmp);
VRFY((mpi_size_tmp == mpi_size), "MPI_Comm_size");
VRFY((mpi_rank_tmp == mpi_rank), "MPI_Comm_rank");
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_get_nkeys");
VRFY((nkeys_tmp == nkeys), "new and old nkeys equal");
}
#if 0
if (VERBOSE_MED)
h5_dump_info_object(info_tmp);
#endif
/* Case 3:
* Close the property list and verify the retrieved communicator and INFO
* object are still valid.
*/
H5Pclose(acc_pl);
MPI_Comm_size(comm_tmp, &mpi_size_tmp);
MPI_Comm_rank(comm_tmp, &mpi_rank_tmp);
if (VERBOSE_MED)
HDprintf("After Property list closed: rank/size of comm are %d/%d\n", mpi_rank_tmp, mpi_size_tmp);
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_get_nkeys");
}
#if 0
if (VERBOSE_MED)
h5_dump_info_object(info_tmp);
#endif
/* clean up */
mrc = MPI_Comm_free(&comm_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free");
if (MPI_INFO_NULL != info_tmp) {
mrc = MPI_Info_free(&info_tmp);
VRFY((mrc == MPI_SUCCESS), "MPI_Info_free");
}
} /* end test_fapl_mpio_dup() */
+646
View File
@@ -0,0 +1,646 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Parallel tests for encoding/decoding plists sent between processes
*/
#include "hdf5.h"
#include "testphdf5.h"
#if 0
#include "H5ACprivate.h"
#include "H5Pprivate.h"
#endif
static int
test_encode_decode(hid_t orig_pl, int mpi_rank, int recv_proc)
{
MPI_Request req[2];
MPI_Status status;
hid_t pl; /* Decoded property list */
size_t buf_size = 0;
void *sbuf = NULL;
herr_t ret; /* Generic return value */
if (mpi_rank == 0) {
int send_size = 0;
/* first call to encode returns only the size of the buffer needed */
ret = H5Pencode2(orig_pl, NULL, &buf_size, H5P_DEFAULT);
VRFY((ret >= 0), "H5Pencode succeeded");
sbuf = (uint8_t *)HDmalloc(buf_size);
ret = H5Pencode2(orig_pl, sbuf, &buf_size, H5P_DEFAULT);
VRFY((ret >= 0), "H5Pencode succeeded");
/* this is a temp fix to send this size_t */
send_size = (int)buf_size;
MPI_Isend(&send_size, 1, MPI_INT, recv_proc, 123, MPI_COMM_WORLD, &req[0]);
MPI_Isend(sbuf, send_size, MPI_BYTE, recv_proc, 124, MPI_COMM_WORLD, &req[1]);
} /* end if */
if (mpi_rank == recv_proc) {
int recv_size;
void *rbuf;
MPI_Recv(&recv_size, 1, MPI_INT, 0, 123, MPI_COMM_WORLD, &status);
VRFY((recv_size >= 0), "MPI_Recv succeeded");
buf_size = (size_t)recv_size;
rbuf = (uint8_t *)HDmalloc(buf_size);
MPI_Recv(rbuf, recv_size, MPI_BYTE, 0, 124, MPI_COMM_WORLD, &status);
pl = H5Pdecode(rbuf);
VRFY((pl >= 0), "H5Pdecode succeeded");
VRFY(H5Pequal(orig_pl, pl), "Property List Equal Succeeded");
ret = H5Pclose(pl);
VRFY((ret >= 0), "H5Pclose succeeded");
if (NULL != rbuf)
HDfree(rbuf);
} /* end if */
if (0 == mpi_rank) {
/* gcc 11 complains about passing MPI_STATUSES_IGNORE as an MPI_Status
* array. See the discussion here:
*
* https://github.com/pmodels/mpich/issues/5687
*/
/* H5_GCC_DIAG_OFF("stringop-overflow") */
MPI_Waitall(2, req, MPI_STATUSES_IGNORE);
/* H5_GCC_DIAG_ON("stringop-overflow") */
}
if (NULL != sbuf)
HDfree(sbuf);
MPI_Barrier(MPI_COMM_WORLD);
return 0;
}
void
test_plist_ed(void)
{
hid_t dcpl; /* dataset create prop. list */
hid_t dapl; /* dataset access prop. list */
hid_t dxpl; /* dataset transfer prop. list */
hid_t gcpl; /* group create prop. list */
hid_t lcpl; /* link create prop. list */
hid_t lapl; /* link access prop. list */
hid_t ocpypl; /* object copy prop. list */
hid_t ocpl; /* object create prop. list */
hid_t fapl; /* file access prop. list */
hid_t fcpl; /* file create prop. list */
hid_t strcpl; /* string create prop. list */
hid_t acpl; /* attribute create prop. list */
int mpi_size, mpi_rank, recv_proc;
hsize_t chunk_size = 16384; /* chunk size */
double fill = 2.7; /* Fill value */
size_t nslots = 521 * 2;
size_t nbytes = 1048576 * 10;
double w0 = 0.5;
unsigned max_compact;
unsigned min_dense;
hsize_t max_size[1]; /*data space maximum size */
const char *c_to_f = "x+32";
H5AC_cache_config_t my_cache_config = {H5AC__CURR_CACHE_CONFIG_VERSION,
TRUE,
FALSE,
FALSE,
"temp",
TRUE,
FALSE,
(2 * 2048 * 1024),
0.3,
(64 * 1024 * 1024),
(4 * 1024 * 1024),
60000,
H5C_incr__threshold,
0.8,
3.0,
TRUE,
(8 * 1024 * 1024),
H5C_flash_incr__add_space,
2.0,
0.25,
H5C_decr__age_out_with_threshold,
0.997,
0.8,
TRUE,
(3 * 1024 * 1024),
3,
FALSE,
0.2,
(256 * 2048),
1 /* H5AC__DEFAULT_METADATA_WRITE_STRATEGY */};
herr_t ret; /* Generic return value */
if (VERBOSE_MED)
HDprintf("Encode/Decode DCPLs\n");
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if (mpi_size == 1)
recv_proc = 0;
else
recv_proc = 1;
dcpl = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk(dcpl, 1, &chunk_size);
VRFY((ret >= 0), "H5Pset_chunk succeeded");
ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_LATE);
VRFY((ret >= 0), "H5Pset_alloc_time succeeded");
ret = H5Pset_fill_value(dcpl, H5T_NATIVE_DOUBLE, &fill);
VRFY((ret >= 0), "set fill-value succeeded");
max_size[0] = 100;
ret = H5Pset_external(dcpl, "ext1.data", (off_t)0, (hsize_t)(max_size[0] * sizeof(int) / 4));
VRFY((ret >= 0), "set external succeeded");
ret = H5Pset_external(dcpl, "ext2.data", (off_t)0, (hsize_t)(max_size[0] * sizeof(int) / 4));
VRFY((ret >= 0), "set external succeeded");
ret = H5Pset_external(dcpl, "ext3.data", (off_t)0, (hsize_t)(max_size[0] * sizeof(int) / 4));
VRFY((ret >= 0), "set external succeeded");
ret = H5Pset_external(dcpl, "ext4.data", (off_t)0, (hsize_t)(max_size[0] * sizeof(int) / 4));
VRFY((ret >= 0), "set external succeeded");
ret = test_encode_decode(dcpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(dcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE DAPLS *****/
dapl = H5Pcreate(H5P_DATASET_ACCESS);
VRFY((dapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_chunk_cache(dapl, nslots, nbytes, w0);
VRFY((ret >= 0), "H5Pset_chunk_cache succeeded");
ret = test_encode_decode(dapl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(dapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE OCPLS *****/
ocpl = H5Pcreate(H5P_OBJECT_CREATE);
VRFY((ocpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_attr_creation_order(ocpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED));
VRFY((ret >= 0), "H5Pset_attr_creation_order succeeded");
ret = H5Pset_attr_phase_change(ocpl, 110, 105);
VRFY((ret >= 0), "H5Pset_attr_phase_change succeeded");
ret = H5Pset_filter(ocpl, H5Z_FILTER_FLETCHER32, 0, (size_t)0, NULL);
VRFY((ret >= 0), "H5Pset_filter succeeded");
ret = test_encode_decode(ocpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(ocpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE DXPLS *****/
dxpl = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_btree_ratios(dxpl, 0.2, 0.6, 0.2);
VRFY((ret >= 0), "H5Pset_btree_ratios succeeded");
ret = H5Pset_hyper_vector_size(dxpl, 5);
VRFY((ret >= 0), "H5Pset_hyper_vector_size succeeded");
ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
ret = H5Pset_dxpl_mpio_collective_opt(dxpl, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_collective_opt succeeded");
ret = H5Pset_dxpl_mpio_chunk_opt(dxpl, H5FD_MPIO_CHUNK_MULTI_IO);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt succeeded");
ret = H5Pset_dxpl_mpio_chunk_opt_ratio(dxpl, 30);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_ratio succeeded");
ret = H5Pset_dxpl_mpio_chunk_opt_num(dxpl, 40);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_num succeeded");
ret = H5Pset_edc_check(dxpl, H5Z_DISABLE_EDC);
VRFY((ret >= 0), "H5Pset_edc_check succeeded");
ret = H5Pset_data_transform(dxpl, c_to_f);
VRFY((ret >= 0), "H5Pset_data_transform succeeded");
ret = test_encode_decode(dxpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(dxpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE GCPLS *****/
gcpl = H5Pcreate(H5P_GROUP_CREATE);
VRFY((gcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_local_heap_size_hint(gcpl, 256);
VRFY((ret >= 0), "H5Pset_local_heap_size_hint succeeded");
ret = H5Pset_link_phase_change(gcpl, 2, 2);
VRFY((ret >= 0), "H5Pset_link_phase_change succeeded");
/* Query the group creation properties */
ret = H5Pget_link_phase_change(gcpl, &max_compact, &min_dense);
VRFY((ret >= 0), "H5Pget_est_link_info succeeded");
ret = H5Pset_est_link_info(gcpl, 3, 9);
VRFY((ret >= 0), "H5Pset_est_link_info succeeded");
ret = H5Pset_link_creation_order(gcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED));
VRFY((ret >= 0), "H5Pset_link_creation_order succeeded");
ret = test_encode_decode(gcpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(gcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE LCPLS *****/
lcpl = H5Pcreate(H5P_LINK_CREATE);
VRFY((lcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_create_intermediate_group(lcpl, TRUE);
VRFY((ret >= 0), "H5Pset_create_intermediate_group succeeded");
ret = test_encode_decode(lcpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(lcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE LAPLS *****/
lapl = H5Pcreate(H5P_LINK_ACCESS);
VRFY((lapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_nlinks(lapl, (size_t)134);
VRFY((ret >= 0), "H5Pset_nlinks succeeded");
ret = H5Pset_elink_acc_flags(lapl, H5F_ACC_RDONLY);
VRFY((ret >= 0), "H5Pset_elink_acc_flags succeeded");
ret = H5Pset_elink_prefix(lapl, "/tmpasodiasod");
VRFY((ret >= 0), "H5Pset_nlinks succeeded");
/* Create FAPL for the elink FAPL */
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_alignment(fapl, 2, 1024);
VRFY((ret >= 0), "H5Pset_alignment succeeded");
ret = H5Pset_elink_fapl(lapl, fapl);
VRFY((ret >= 0), "H5Pset_elink_fapl succeeded");
/* Close the elink's FAPL */
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = test_encode_decode(lapl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(lapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE OCPYPLS *****/
ocpypl = H5Pcreate(H5P_OBJECT_COPY);
VRFY((ocpypl >= 0), "H5Pcreate succeeded");
ret = H5Pset_copy_object(ocpypl, H5O_COPY_EXPAND_EXT_LINK_FLAG);
VRFY((ret >= 0), "H5Pset_copy_object succeeded");
ret = H5Padd_merge_committed_dtype_path(ocpypl, "foo");
VRFY((ret >= 0), "H5Padd_merge_committed_dtype_path succeeded");
ret = H5Padd_merge_committed_dtype_path(ocpypl, "bar");
VRFY((ret >= 0), "H5Padd_merge_committed_dtype_path succeeded");
ret = test_encode_decode(ocpypl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(ocpypl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE FAPLS *****/
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_family_offset(fapl, 1024);
VRFY((ret >= 0), "H5Pset_family_offset succeeded");
ret = H5Pset_meta_block_size(fapl, 2098452);
VRFY((ret >= 0), "H5Pset_meta_block_size succeeded");
ret = H5Pset_sieve_buf_size(fapl, 1048576);
VRFY((ret >= 0), "H5Pset_sieve_buf_size succeeded");
ret = H5Pset_alignment(fapl, 2, 1024);
VRFY((ret >= 0), "H5Pset_alignment succeeded");
ret = H5Pset_cache(fapl, 1024, 128, 10485760, 0.3);
VRFY((ret >= 0), "H5Pset_cache succeeded");
ret = H5Pset_elink_file_cache_size(fapl, 10485760);
VRFY((ret >= 0), "H5Pset_elink_file_cache_size succeeded");
ret = H5Pset_gc_references(fapl, 1);
VRFY((ret >= 0), "H5Pset_gc_references succeeded");
ret = H5Pset_small_data_block_size(fapl, 2048);
VRFY((ret >= 0), "H5Pset_small_data_block_size succeeded");
ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
VRFY((ret >= 0), "H5Pset_libver_bounds succeeded");
ret = H5Pset_fclose_degree(fapl, H5F_CLOSE_WEAK);
VRFY((ret >= 0), "H5Pset_fclose_degree succeeded");
ret = H5Pset_multi_type(fapl, H5FD_MEM_GHEAP);
VRFY((ret >= 0), "H5Pset_multi_type succeeded");
ret = H5Pset_mdc_config(fapl, &my_cache_config);
VRFY((ret >= 0), "H5Pset_mdc_config succeeded");
ret = test_encode_decode(fapl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE FCPLS *****/
fcpl = H5Pcreate(H5P_FILE_CREATE);
VRFY((fcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_userblock(fcpl, 1024);
VRFY((ret >= 0), "H5Pset_userblock succeeded");
ret = H5Pset_istore_k(fcpl, 3);
VRFY((ret >= 0), "H5Pset_istore_k succeeded");
ret = H5Pset_sym_k(fcpl, 4, 5);
VRFY((ret >= 0), "H5Pset_sym_k succeeded");
ret = H5Pset_shared_mesg_nindexes(fcpl, 8);
VRFY((ret >= 0), "H5Pset_shared_mesg_nindexes succeeded");
ret = H5Pset_shared_mesg_index(fcpl, 1, H5O_SHMESG_SDSPACE_FLAG, 32);
VRFY((ret >= 0), "H5Pset_shared_mesg_index succeeded");
ret = H5Pset_shared_mesg_phase_change(fcpl, 60, 20);
VRFY((ret >= 0), "H5Pset_shared_mesg_phase_change succeeded");
ret = H5Pset_sizes(fcpl, 8, 4);
VRFY((ret >= 0), "H5Pset_sizes succeeded");
ret = test_encode_decode(fcpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(fcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE STRCPLS *****/
strcpl = H5Pcreate(H5P_STRING_CREATE);
VRFY((strcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_char_encoding(strcpl, H5T_CSET_UTF8);
VRFY((ret >= 0), "H5Pset_char_encoding succeeded");
ret = test_encode_decode(strcpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(strcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
/******* ENCODE/DECODE ACPLS *****/
acpl = H5Pcreate(H5P_ATTRIBUTE_CREATE);
VRFY((acpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_char_encoding(acpl, H5T_CSET_UTF8);
VRFY((ret >= 0), "H5Pset_char_encoding succeeded");
ret = test_encode_decode(acpl, mpi_rank, recv_proc);
VRFY((ret >= 0), "test_encode_decode succeeded");
ret = H5Pclose(acpl);
VRFY((ret >= 0), "H5Pclose succeeded");
}
#if 0
void
external_links(void)
{
hid_t lcpl = H5I_INVALID_HID; /* link create prop. list */
hid_t lapl = H5I_INVALID_HID; /* link access prop. list */
hid_t fapl = H5I_INVALID_HID; /* file access prop. list */
hid_t gapl = H5I_INVALID_HID; /* group access prop. list */
hid_t fid = H5I_INVALID_HID; /* file id */
hid_t group = H5I_INVALID_HID; /* group id */
int mpi_size, mpi_rank;
MPI_Comm comm;
int doIO;
int i, mrc;
herr_t ret; /* Generic return value */
htri_t tri_status; /* tri return value */
const char *filename = "HDF5test.h5";
const char *filename_ext = "HDF5test_ext.h5";
const char *group_path = "/Base/Block/Step";
const char *link_name = "link"; /* external link */
char link_path[50];
if (VERBOSE_MED)
HDprintf("Check external links\n");
/* set up MPI parameters */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Check MPI communicator access properties are passed to
linked external files */
if (mpi_rank == 0) {
lcpl = H5Pcreate(H5P_LINK_CREATE);
VRFY((lcpl >= 0), "H5Pcreate succeeded");
ret = H5Pset_create_intermediate_group(lcpl, 1);
VRFY((ret >= 0), "H5Pset_create_intermediate_group succeeded");
/* Create file to serve as target for external link.*/
fid = H5Fcreate(filename_ext, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
VRFY((fid >= 0), "H5Fcreate succeeded");
group = H5Gcreate2(fid, group_path, lcpl, H5P_DEFAULT, H5P_DEFAULT);
VRFY((group >= 0), "H5Gcreate succeeded");
ret = H5Gclose(group);
VRFY((ret >= 0), "H5Gclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
/* Create a new file using the file access property list. */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((fid >= 0), "H5Fcreate succeeded");
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
group = H5Gcreate2(fid, group_path, lcpl, H5P_DEFAULT, H5P_DEFAULT);
VRFY((group >= 0), "H5Gcreate succeeded");
/* Create external links to the target files. */
ret = H5Lcreate_external(filename_ext, group_path, group, link_name, H5P_DEFAULT, H5P_DEFAULT);
VRFY((ret >= 0), "H5Lcreate_external succeeded");
/* Close and release resources. */
ret = H5Pclose(lcpl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Gclose(group);
VRFY((ret >= 0), "H5Gclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
MPI_Barrier(MPI_COMM_WORLD);
/*
* For the first case, use all the processes. For the second case
* use a sub-communicator to verify the correct communicator is
* being used for the externally linked files.
* There is no way to determine if MPI info is being used for the
* externally linked files.
*/
for (i = 0; i < 2; i++) {
comm = MPI_COMM_WORLD;
if (i == 0)
doIO = 1;
else {
doIO = mpi_rank % 2;
mrc = MPI_Comm_split(MPI_COMM_WORLD, doIO, mpi_rank, &comm);
VRFY((mrc == MPI_SUCCESS), "");
}
if (doIO) {
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_fapl_mpio(fapl, comm, MPI_INFO_NULL);
VRFY((fapl >= 0), "H5Pset_fapl_mpio succeeded");
fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
VRFY((fid >= 0), "H5Fopen succeeded");
/* test opening a group that is to an external link, the external linked
file should inherit the source file's access properties */
HDsnprintf(link_path, sizeof(link_path), "%s%s%s", group_path, "/", link_name);
group = H5Gopen2(fid, link_path, H5P_DEFAULT);
VRFY((group >= 0), "H5Gopen succeeded");
ret = H5Gclose(group);
VRFY((ret >= 0), "H5Gclose succeeded");
/* test opening a group that is external link by setting group
creation property */
gapl = H5Pcreate(H5P_GROUP_ACCESS);
VRFY((gapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_elink_fapl(gapl, fapl);
VRFY((ret >= 0), "H5Pset_elink_fapl succeeded");
group = H5Gopen2(fid, link_path, gapl);
VRFY((group >= 0), "H5Gopen succeeded");
ret = H5Gclose(group);
VRFY((ret >= 0), "H5Gclose succeeded");
ret = H5Pclose(gapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* test link APIs */
lapl = H5Pcreate(H5P_LINK_ACCESS);
VRFY((lapl >= 0), "H5Pcreate succeeded");
ret = H5Pset_elink_fapl(lapl, fapl);
VRFY((ret >= 0), "H5Pset_elink_fapl succeeded");
tri_status = H5Lexists(fid, link_path, H5P_DEFAULT);
VRFY((tri_status == TRUE), "H5Lexists succeeded");
tri_status = H5Lexists(fid, link_path, lapl);
VRFY((tri_status == TRUE), "H5Lexists succeeded");
group = H5Oopen(fid, link_path, H5P_DEFAULT);
VRFY((group >= 0), "H5Oopen succeeded");
ret = H5Oclose(group);
VRFY((ret >= 0), "H5Oclose succeeded");
group = H5Oopen(fid, link_path, lapl);
VRFY((group >= 0), "H5Oopen succeeded");
ret = H5Oclose(group);
VRFY((ret >= 0), "H5Oclose succeeded");
ret = H5Pclose(lapl);
VRFY((ret >= 0), "H5Pclose succeeded");
/* close the remaining resources */
ret = H5Pclose(fapl);
VRFY((ret >= 0), "H5Pclose succeeded");
ret = H5Fclose(fid);
VRFY((ret >= 0), "H5Fclose succeeded");
}
if (comm != MPI_COMM_WORLD) {
mrc = MPI_Comm_free(&comm);
VRFY((mrc == MPI_SUCCESS), "MPI_Comm_free succeeded");
}
}
MPI_Barrier(MPI_COMM_WORLD);
/* delete the test files */
if (mpi_rank == 0) {
MPI_File_delete(filename, MPI_INFO_NULL);
MPI_File_delete(filename_ext, MPI_INFO_NULL);
}
}
#endif
+150
View File
@@ -0,0 +1,150 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Programmer: Mohamad Chaarawi
* February 2015
*
* Purpose: This test creates a file and a bunch of objects in the
* file and then calls MPI_Finalize without closing anything. The
* library should exercise the attribute callback destroy attached to
* MPI_COMM_SELF and terminate the HDF5 library closing all open
* objects. The t_prestart test will read back the file and make sure
* all created objects are there.
*/
#include "hdf5.h"
#include "testphdf5.h"
int nerrors = 0; /* errors count */
const char *FILENAME[] = {"shutdown.h5", NULL};
int
main(int argc, char **argv)
{
hid_t file_id, dset_id, grp_id;
hid_t fapl, sid, mem_dataspace;
hsize_t dims[RANK], i;
herr_t ret;
#if 0
char filename[1024];
#endif
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
hsize_t start[RANK];
hsize_t count[RANK];
hsize_t stride[RANK];
hsize_t block[RANK];
DATATYPE *data_array = NULL; /* data buffer */
MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
if (MAINPROCESS) {
printf("Testing %-62s", "proper shutdown of HDF5 library");
fflush(stdout);
}
/* Set up file access property list with parallel I/O access */
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
/* Get the capability flag of the VOL connector being used */
ret = H5Pget_vol_cap_flags(fapl, &vol_cap_flags_g);
VRFY((ret >= 0), "H5Pget_vol_cap_flags succeeded");
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
HDprintf(
" API functions for basic file, group, or dataset aren't supported with this connector\n");
fflush(stdout);
}
MPI_Finalize();
return 0;
}
ret = H5Pset_fapl_mpio(fapl, comm, info);
VRFY((ret >= 0), "");
#if 0
h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
#endif
file_id = H5Fcreate(FILENAME[0], H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
VRFY((file_id >= 0), "H5Fcreate succeeded");
grp_id = H5Gcreate2(file_id, "Group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((grp_id >= 0), "H5Gcreate succeeded");
dims[0] = (hsize_t)ROW_FACTOR * (hsize_t)mpi_size;
dims[1] = (hsize_t)COL_FACTOR * (hsize_t)mpi_size;
sid = H5Screate_simple(RANK, dims, NULL);
VRFY((sid >= 0), "H5Screate_simple succeeded");
dset_id = H5Dcreate2(grp_id, "Dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate succeeded");
/* allocate memory for data buffer */
data_array = (DATATYPE *)HDmalloc(dims[0] * dims[1] * sizeof(DATATYPE));
VRFY((data_array != NULL), "data_array HDmalloc succeeded");
/* Each process takes a slabs of rows. */
block[0] = dims[0] / (hsize_t)mpi_size;
block[1] = dims[1];
stride[0] = block[0];
stride[1] = block[1];
count[0] = 1;
count[1] = 1;
start[0] = (hsize_t)mpi_rank * block[0];
start[1] = 0;
/* put some trivial data in the data_array */
for (i = 0; i < dims[0] * dims[1]; i++)
data_array[i] = mpi_rank + 1;
ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
/* create a memory dataspace independently */
mem_dataspace = H5Screate_simple(RANK, block, NULL);
VRFY((mem_dataspace >= 0), "");
/* write data independently */
ret = H5Dwrite(dset_id, H5T_NATIVE_INT, mem_dataspace, sid, H5P_DEFAULT, data_array);
VRFY((ret >= 0), "H5Dwrite succeeded");
/* release data buffers */
if (data_array)
HDfree(data_array);
MPI_Finalize();
/* nerrors += GetTestNumErrs(); */
if (MAINPROCESS) {
if (0 == nerrors) {
puts(" PASSED");
fflush(stdout);
}
else {
puts("*FAILED*");
fflush(stdout);
}
}
return (nerrors != 0);
}
+4516
View File
@@ -0,0 +1,4516 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
This program will test independent and collective reads and writes between
selections of different rank that non-the-less are deemed as having the
same shape by H5Sselect_shape_same().
*/
#define H5S_FRIEND /*suppress error about including H5Spkg */
/* Define this macro to indicate that the testing APIs should be available */
#define H5S_TESTING
#if 0
#include "H5Spkg.h" /* Dataspaces */
#endif
#include "hdf5.h"
#include "testphdf5.h"
/* FILENAME and filenames must have the same number of names.
* Use PARATESTFILE in general and use a separated filename only if the file
* created in one test is accessed by a different test.
* filenames[0] is reserved as the file name for PARATESTFILE.
*/
#define NFILENAME 2
const char *FILENAME[NFILENAME] = {"ShapeSameTest.h5", NULL};
char filenames[NFILENAME][PATH_MAX];
hid_t fapl; /* file access property list */
/* On Lustre (and perhaps other parallel file systems?), we have severe
* slow downs if two or more processes attempt to access the same file system
* block. To minimize this problem, we set alignment in the shape same tests
* to the default Lustre block size -- which greatly reduces contention in
* the chunked dataset case.
*/
#define SHAPE_SAME_TEST_ALIGNMENT ((hsize_t)(4 * 1024 * 1024))
#define PAR_SS_DR_MAX_RANK 5 /* must update code if this changes */
struct hs_dr_pio_test_vars_t {
int mpi_size;
int mpi_rank;
MPI_Comm mpi_comm;
MPI_Info mpi_info;
int test_num;
int edge_size;
int checker_edge_size;
int chunk_edge_size;
int small_rank;
int large_rank;
hid_t dset_type;
uint32_t *small_ds_buf_0;
uint32_t *small_ds_buf_1;
uint32_t *small_ds_buf_2;
uint32_t *small_ds_slice_buf;
uint32_t *large_ds_buf_0;
uint32_t *large_ds_buf_1;
uint32_t *large_ds_buf_2;
uint32_t *large_ds_slice_buf;
int small_ds_offset;
int large_ds_offset;
hid_t fid; /* HDF5 file ID */
hid_t xfer_plist;
hid_t full_mem_small_ds_sid;
hid_t full_file_small_ds_sid;
hid_t mem_small_ds_sid;
hid_t file_small_ds_sid_0;
hid_t file_small_ds_sid_1;
hid_t small_ds_slice_sid;
hid_t full_mem_large_ds_sid;
hid_t full_file_large_ds_sid;
hid_t mem_large_ds_sid;
hid_t file_large_ds_sid_0;
hid_t file_large_ds_sid_1;
hid_t file_large_ds_process_slice_sid;
hid_t mem_large_ds_process_slice_sid;
hid_t large_ds_slice_sid;
hid_t small_dataset; /* Dataset ID */
hid_t large_dataset; /* Dataset ID */
size_t small_ds_size;
size_t small_ds_slice_size;
size_t large_ds_size;
size_t large_ds_slice_size;
hsize_t dims[PAR_SS_DR_MAX_RANK];
hsize_t chunk_dims[PAR_SS_DR_MAX_RANK];
hsize_t start[PAR_SS_DR_MAX_RANK];
hsize_t stride[PAR_SS_DR_MAX_RANK];
hsize_t count[PAR_SS_DR_MAX_RANK];
hsize_t block[PAR_SS_DR_MAX_RANK];
hsize_t *start_ptr;
hsize_t *stride_ptr;
hsize_t *count_ptr;
hsize_t *block_ptr;
int skips;
int max_skips;
int64_t total_tests;
int64_t tests_run;
int64_t tests_skipped;
};
/*-------------------------------------------------------------------------
* Function: hs_dr_pio_test__setup()
*
* Purpose: Do setup for tests of I/O to/from hyperslab selections of
* different rank in the parallel case.
*
* Return: void
*
* Programmer: JRM -- 8/9/11
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG 0
static void
hs_dr_pio_test__setup(const int test_num, const int edge_size, const int checker_edge_size,
const int chunk_edge_size, const int small_rank, const int large_rank,
const hbool_t use_collective_io, const hid_t dset_type, const int express_test,
struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG
const char *fcnName = "hs_dr_pio_test__setup()";
#endif /* CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG */
const char *filename;
hbool_t mis_match = FALSE;
int i;
int mrc;
int mpi_rank; /* needed by the VRFY macro */
uint32_t expected_value;
uint32_t *ptr_0;
uint32_t *ptr_1;
hid_t acc_tpl; /* File access templates */
hid_t small_ds_dcpl_id = H5P_DEFAULT;
hid_t large_ds_dcpl_id = H5P_DEFAULT;
herr_t ret; /* Generic return value */
HDassert(edge_size >= 6);
HDassert(edge_size >= chunk_edge_size);
HDassert((chunk_edge_size == 0) || (chunk_edge_size >= 3));
HDassert(1 < small_rank);
HDassert(small_rank < large_rank);
HDassert(large_rank <= PAR_SS_DR_MAX_RANK);
tv_ptr->test_num = test_num;
tv_ptr->edge_size = edge_size;
tv_ptr->checker_edge_size = checker_edge_size;
tv_ptr->chunk_edge_size = chunk_edge_size;
tv_ptr->small_rank = small_rank;
tv_ptr->large_rank = large_rank;
tv_ptr->dset_type = dset_type;
MPI_Comm_size(MPI_COMM_WORLD, &(tv_ptr->mpi_size));
MPI_Comm_rank(MPI_COMM_WORLD, &(tv_ptr->mpi_rank));
/* the VRFY() macro needs the local variable mpi_rank -- set it up now */
mpi_rank = tv_ptr->mpi_rank;
HDassert(tv_ptr->mpi_size >= 1);
tv_ptr->mpi_comm = MPI_COMM_WORLD;
tv_ptr->mpi_info = MPI_INFO_NULL;
for (i = 0; i < tv_ptr->small_rank - 1; i++) {
tv_ptr->small_ds_size *= (size_t)(tv_ptr->edge_size);
tv_ptr->small_ds_slice_size *= (size_t)(tv_ptr->edge_size);
}
tv_ptr->small_ds_size *= (size_t)(tv_ptr->mpi_size + 1);
/* used by checker board tests only */
tv_ptr->small_ds_offset = PAR_SS_DR_MAX_RANK - tv_ptr->small_rank;
HDassert(0 < tv_ptr->small_ds_offset);
HDassert(tv_ptr->small_ds_offset < PAR_SS_DR_MAX_RANK);
for (i = 0; i < tv_ptr->large_rank - 1; i++) {
tv_ptr->large_ds_size *= (size_t)(tv_ptr->edge_size);
tv_ptr->large_ds_slice_size *= (size_t)(tv_ptr->edge_size);
}
tv_ptr->large_ds_size *= (size_t)(tv_ptr->mpi_size + 1);
/* used by checker board tests only */
tv_ptr->large_ds_offset = PAR_SS_DR_MAX_RANK - tv_ptr->large_rank;
HDassert(0 <= tv_ptr->large_ds_offset);
HDassert(tv_ptr->large_ds_offset < PAR_SS_DR_MAX_RANK);
/* set up the start, stride, count, and block pointers */
/* used by contiguous tests only */
tv_ptr->start_ptr = &(tv_ptr->start[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
tv_ptr->stride_ptr = &(tv_ptr->stride[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
tv_ptr->count_ptr = &(tv_ptr->count[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
tv_ptr->block_ptr = &(tv_ptr->block[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
/* Allocate buffers */
tv_ptr->small_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
VRFY((tv_ptr->small_ds_buf_0 != NULL), "malloc of small_ds_buf_0 succeeded");
tv_ptr->small_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
VRFY((tv_ptr->small_ds_buf_1 != NULL), "malloc of small_ds_buf_1 succeeded");
tv_ptr->small_ds_buf_2 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
VRFY((tv_ptr->small_ds_buf_2 != NULL), "malloc of small_ds_buf_2 succeeded");
tv_ptr->small_ds_slice_buf = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
VRFY((tv_ptr->small_ds_slice_buf != NULL), "malloc of small_ds_slice_buf succeeded");
tv_ptr->large_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
VRFY((tv_ptr->large_ds_buf_0 != NULL), "malloc of large_ds_buf_0 succeeded");
tv_ptr->large_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
VRFY((tv_ptr->large_ds_buf_1 != NULL), "malloc of large_ds_buf_1 succeeded");
tv_ptr->large_ds_buf_2 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
VRFY((tv_ptr->large_ds_buf_2 != NULL), "malloc of large_ds_buf_2 succeeded");
tv_ptr->large_ds_slice_buf = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_slice_size);
VRFY((tv_ptr->large_ds_slice_buf != NULL), "malloc of large_ds_slice_buf succeeded");
/* initialize the buffers */
ptr_0 = tv_ptr->small_ds_buf_0;
for (i = 0; i < (int)(tv_ptr->small_ds_size); i++)
*ptr_0++ = (uint32_t)i;
HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
HDmemset(tv_ptr->small_ds_buf_2, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
ptr_0 = tv_ptr->large_ds_buf_0;
for (i = 0; i < (int)(tv_ptr->large_ds_size); i++)
*ptr_0++ = (uint32_t)i;
HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
HDmemset(tv_ptr->large_ds_buf_2, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
HDmemset(tv_ptr->large_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->large_ds_slice_size);
filename = filenames[0]; /* (const char *)GetTestParameters(); */
HDassert(filename != NULL);
#if CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "%d: test num = %d.\n", tv_ptr->mpi_rank, tv_ptr->test_num);
HDfprintf(stdout, "%d: mpi_size = %d.\n", tv_ptr->mpi_rank, tv_ptr->mpi_size);
HDfprintf(stdout, "%d: small/large rank = %d/%d, use_collective_io = %d.\n", tv_ptr->mpi_rank,
tv_ptr->small_rank, tv_ptr->large_rank, (int)use_collective_io);
HDfprintf(stdout, "%d: edge_size = %d, chunk_edge_size = %d.\n", tv_ptr->mpi_rank, tv_ptr->edge_size,
tv_ptr->chunk_edge_size);
HDfprintf(stdout, "%d: checker_edge_size = %d.\n", tv_ptr->mpi_rank, tv_ptr->checker_edge_size);
HDfprintf(stdout, "%d: small_ds_size = %d, large_ds_size = %d.\n", tv_ptr->mpi_rank,
(int)(tv_ptr->small_ds_size), (int)(tv_ptr->large_ds_size));
HDfprintf(stdout, "%d: filename = %s.\n", tv_ptr->mpi_rank, filename);
}
#endif /* CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG */
/* ----------------------------------------
* CREATE AN HDF5 FILE WITH PARALLEL ACCESS
* ---------------------------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(tv_ptr->mpi_comm, tv_ptr->mpi_info, facc_type);
VRFY((acc_tpl >= 0), "create_faccess_plist() succeeded");
/* set the alignment -- need it large so that we aren't always hitting the
* the same file system block. Do this only if express_test is greater
* than zero.
*/
if (express_test > 0) {
ret = H5Pset_alignment(acc_tpl, (hsize_t)0, SHAPE_SAME_TEST_ALIGNMENT);
VRFY((ret != FAIL), "H5Pset_alignment() succeeded");
}
/* create the file collectively */
tv_ptr->fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((tv_ptr->fid >= 0), "H5Fcreate succeeded");
MESG("File opened.");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose(acc_tpl) succeeded");
/* setup dims: */
tv_ptr->dims[0] = (hsize_t)(tv_ptr->mpi_size + 1);
tv_ptr->dims[1] = tv_ptr->dims[2] = tv_ptr->dims[3] = tv_ptr->dims[4] = (hsize_t)(tv_ptr->edge_size);
/* Create small ds dataspaces */
tv_ptr->full_mem_small_ds_sid = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->full_mem_small_ds_sid != 0), "H5Screate_simple() full_mem_small_ds_sid succeeded");
tv_ptr->full_file_small_ds_sid = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->full_file_small_ds_sid != 0), "H5Screate_simple() full_file_small_ds_sid succeeded");
tv_ptr->mem_small_ds_sid = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->mem_small_ds_sid != 0), "H5Screate_simple() mem_small_ds_sid succeeded");
tv_ptr->file_small_ds_sid_0 = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->file_small_ds_sid_0 != 0), "H5Screate_simple() file_small_ds_sid_0 succeeded");
/* used by checker board tests only */
tv_ptr->file_small_ds_sid_1 = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->file_small_ds_sid_1 != 0), "H5Screate_simple() file_small_ds_sid_1 succeeded");
tv_ptr->small_ds_slice_sid = H5Screate_simple(tv_ptr->small_rank - 1, &(tv_ptr->dims[1]), NULL);
VRFY((tv_ptr->small_ds_slice_sid != 0), "H5Screate_simple() small_ds_slice_sid succeeded");
/* Create large ds dataspaces */
tv_ptr->full_mem_large_ds_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->full_mem_large_ds_sid != 0), "H5Screate_simple() full_mem_large_ds_sid succeeded");
tv_ptr->full_file_large_ds_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->full_file_large_ds_sid != FAIL), "H5Screate_simple() full_file_large_ds_sid succeeded");
tv_ptr->mem_large_ds_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->mem_large_ds_sid != FAIL), "H5Screate_simple() mem_large_ds_sid succeeded");
tv_ptr->file_large_ds_sid_0 = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->file_large_ds_sid_0 != FAIL), "H5Screate_simple() file_large_ds_sid_0 succeeded");
/* used by checker board tests only */
tv_ptr->file_large_ds_sid_1 = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->file_large_ds_sid_1 != FAIL), "H5Screate_simple() file_large_ds_sid_1 succeeded");
tv_ptr->mem_large_ds_process_slice_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->mem_large_ds_process_slice_sid != FAIL),
"H5Screate_simple() mem_large_ds_process_slice_sid succeeded");
tv_ptr->file_large_ds_process_slice_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
VRFY((tv_ptr->file_large_ds_process_slice_sid != FAIL),
"H5Screate_simple() file_large_ds_process_slice_sid succeeded");
tv_ptr->large_ds_slice_sid = H5Screate_simple(tv_ptr->large_rank - 1, &(tv_ptr->dims[1]), NULL);
VRFY((tv_ptr->large_ds_slice_sid != 0), "H5Screate_simple() large_ds_slice_sid succeeded");
/* if chunk edge size is greater than zero, set up the small and
* large data set creation property lists to specify chunked
* datasets.
*/
if (tv_ptr->chunk_edge_size > 0) {
/* Under Lustre (and perhaps other parallel file systems?) we get
* locking delays when two or more processes attempt to access the
* same file system block.
*
* To minimize this problem, I have changed chunk_dims[0]
* from (mpi_size + 1) to just when any sort of express test is
* selected. Given the structure of the test, and assuming we
* set the alignment large enough, this avoids the contention
* issue by seeing to it that each chunk is only accessed by one
* process.
*
* One can argue as to whether this is a good thing to do in our
* tests, but for now it is necessary if we want the test to complete
* in a reasonable amount of time.
*
* JRM -- 9/16/10
*/
tv_ptr->chunk_dims[0] = 1;
tv_ptr->chunk_dims[1] = tv_ptr->chunk_dims[2] = tv_ptr->chunk_dims[3] = tv_ptr->chunk_dims[4] =
(hsize_t)(tv_ptr->chunk_edge_size);
small_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((ret != FAIL), "H5Pcreate() small_ds_dcpl_id succeeded");
ret = H5Pset_layout(small_ds_dcpl_id, H5D_CHUNKED);
VRFY((ret != FAIL), "H5Pset_layout() small_ds_dcpl_id succeeded");
ret = H5Pset_chunk(small_ds_dcpl_id, tv_ptr->small_rank, tv_ptr->chunk_dims);
VRFY((ret != FAIL), "H5Pset_chunk() small_ds_dcpl_id succeeded");
large_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((ret != FAIL), "H5Pcreate() large_ds_dcpl_id succeeded");
ret = H5Pset_layout(large_ds_dcpl_id, H5D_CHUNKED);
VRFY((ret != FAIL), "H5Pset_layout() large_ds_dcpl_id succeeded");
ret = H5Pset_chunk(large_ds_dcpl_id, tv_ptr->large_rank, tv_ptr->chunk_dims);
VRFY((ret != FAIL), "H5Pset_chunk() large_ds_dcpl_id succeeded");
}
/* create the small dataset */
tv_ptr->small_dataset =
H5Dcreate2(tv_ptr->fid, "small_dataset", tv_ptr->dset_type, tv_ptr->file_small_ds_sid_0, H5P_DEFAULT,
small_ds_dcpl_id, H5P_DEFAULT);
VRFY((ret != FAIL), "H5Dcreate2() small_dataset succeeded");
/* create the large dataset */
tv_ptr->large_dataset =
H5Dcreate2(tv_ptr->fid, "large_dataset", tv_ptr->dset_type, tv_ptr->file_large_ds_sid_0, H5P_DEFAULT,
large_ds_dcpl_id, H5P_DEFAULT);
VRFY((ret != FAIL), "H5Dcreate2() large_dataset succeeded");
/* setup xfer property list */
tv_ptr->xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((tv_ptr->xfer_plist >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
if (use_collective_io) {
ret = H5Pset_dxpl_mpio(tv_ptr->xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
}
/* setup selection to write initial data to the small and large data sets */
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
/* setup selections for writing initial data to the small data set */
ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) succeeded");
if (MAINPROCESS) { /* add an additional slice to the selections */
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_size);
ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid, H5S_SELECT_OR, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, or) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0, H5S_SELECT_OR, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, or) succeeded");
}
/* write the initial value of the small data set to file */
ret = H5Dwrite(tv_ptr->small_dataset, tv_ptr->dset_type, tv_ptr->mem_small_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_0);
VRFY((ret >= 0), "H5Dwrite() small_dataset initial write succeeded");
/* sync with the other processes before checking data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after small dataset writes");
/* read the small data set back to verify that it contains the
* expected data. Note that each process reads in the entire
* data set and verifies it.
*/
ret = H5Dread(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->full_mem_small_ds_sid,
tv_ptr->full_file_small_ds_sid, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_1);
VRFY((ret >= 0), "H5Dread() small_dataset initial read succeeded");
/* verify that the correct data was written to the small data set */
expected_value = 0;
mis_match = FALSE;
ptr_1 = tv_ptr->small_ds_buf_1;
i = 0;
for (i = 0; i < (int)(tv_ptr->small_ds_size); i++) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
ptr_1++;
expected_value++;
}
VRFY((mis_match == FALSE), "small ds init data good.");
/* setup selections for writing initial data to the large data set */
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_sid, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, set) succeeded");
/* In passing, setup the process slice dataspaces as well */
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_process_slice_sid, H5S_SELECT_SET, tv_ptr->start,
tv_ptr->stride, tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_process_slice_sid, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_process_slice_sid, H5S_SELECT_SET, tv_ptr->start,
tv_ptr->stride, tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_process_slice_sid, set) succeeded");
if (MAINPROCESS) { /* add an additional slice to the selections */
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_size);
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, H5S_SELECT_OR, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_sid, or) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0, H5S_SELECT_OR, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, or) succeeded");
}
/* write the initial value of the large data set to file */
ret = H5Dwrite(tv_ptr->large_dataset, tv_ptr->dset_type, tv_ptr->mem_large_ds_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_0);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((ret >= 0), "H5Dwrite() large_dataset initial write succeeded");
/* sync with the other processes before checking data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after large dataset writes");
/* read the large data set back to verify that it contains the
* expected data. Note that each process reads in the entire
* data set.
*/
ret = H5Dread(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->full_mem_large_ds_sid,
tv_ptr->full_file_large_ds_sid, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_1);
VRFY((ret >= 0), "H5Dread() large_dataset initial read succeeded");
/* verify that the correct data was written to the large data set */
expected_value = 0;
mis_match = FALSE;
ptr_1 = tv_ptr->large_ds_buf_1;
i = 0;
for (i = 0; i < (int)(tv_ptr->large_ds_size); i++) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
ptr_1++;
expected_value++;
}
VRFY((mis_match == FALSE), "large ds init data good.");
/* sync with the other processes before changing data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync initial values check");
return;
} /* hs_dr_pio_test__setup() */
/*-------------------------------------------------------------------------
* Function: hs_dr_pio_test__takedown()
*
* Purpose: Do takedown after tests of I/O to/from hyperslab selections
* of different rank in the parallel case.
*
* Return: void
*
* Programmer: JRM -- 9/18/09
*
*-------------------------------------------------------------------------
*/
#define HS_DR_PIO_TEST__TAKEDOWN__DEBUG 0
static void
hs_dr_pio_test__takedown(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if HS_DR_PIO_TEST__TAKEDOWN__DEBUG
const char *fcnName = "hs_dr_pio_test__takedown()";
#endif /* HS_DR_PIO_TEST__TAKEDOWN__DEBUG */
int mpi_rank; /* needed by the VRFY macro */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* Close property lists */
if (tv_ptr->xfer_plist != H5P_DEFAULT) {
ret = H5Pclose(tv_ptr->xfer_plist);
VRFY((ret != FAIL), "H5Pclose(xfer_plist) succeeded");
}
/* Close dataspaces */
ret = H5Sclose(tv_ptr->full_mem_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_mem_small_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->full_file_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_file_small_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->mem_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(mem_small_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->file_small_ds_sid_0);
VRFY((ret != FAIL), "H5Sclose(file_small_ds_sid_0) succeeded");
ret = H5Sclose(tv_ptr->file_small_ds_sid_1);
VRFY((ret != FAIL), "H5Sclose(file_small_ds_sid_1) succeeded");
ret = H5Sclose(tv_ptr->small_ds_slice_sid);
VRFY((ret != FAIL), "H5Sclose(small_ds_slice_sid) succeeded");
ret = H5Sclose(tv_ptr->full_mem_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_mem_large_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->full_file_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_file_large_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->mem_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(mem_large_ds_sid) succeeded");
ret = H5Sclose(tv_ptr->file_large_ds_sid_0);
VRFY((ret != FAIL), "H5Sclose(file_large_ds_sid_0) succeeded");
ret = H5Sclose(tv_ptr->file_large_ds_sid_1);
VRFY((ret != FAIL), "H5Sclose(file_large_ds_sid_1) succeeded");
ret = H5Sclose(tv_ptr->mem_large_ds_process_slice_sid);
VRFY((ret != FAIL), "H5Sclose(mem_large_ds_process_slice_sid) succeeded");
ret = H5Sclose(tv_ptr->file_large_ds_process_slice_sid);
VRFY((ret != FAIL), "H5Sclose(file_large_ds_process_slice_sid) succeeded");
ret = H5Sclose(tv_ptr->large_ds_slice_sid);
VRFY((ret != FAIL), "H5Sclose(large_ds_slice_sid) succeeded");
/* Close Datasets */
ret = H5Dclose(tv_ptr->small_dataset);
VRFY((ret != FAIL), "H5Dclose(small_dataset) succeeded");
ret = H5Dclose(tv_ptr->large_dataset);
VRFY((ret != FAIL), "H5Dclose(large_dataset) succeeded");
/* close the file collectively */
MESG("about to close file.");
ret = H5Fclose(tv_ptr->fid);
VRFY((ret != FAIL), "file close succeeded");
/* Free memory buffers */
if (tv_ptr->small_ds_buf_0 != NULL)
HDfree(tv_ptr->small_ds_buf_0);
if (tv_ptr->small_ds_buf_1 != NULL)
HDfree(tv_ptr->small_ds_buf_1);
if (tv_ptr->small_ds_buf_2 != NULL)
HDfree(tv_ptr->small_ds_buf_2);
if (tv_ptr->small_ds_slice_buf != NULL)
HDfree(tv_ptr->small_ds_slice_buf);
if (tv_ptr->large_ds_buf_0 != NULL)
HDfree(tv_ptr->large_ds_buf_0);
if (tv_ptr->large_ds_buf_1 != NULL)
HDfree(tv_ptr->large_ds_buf_1);
if (tv_ptr->large_ds_buf_2 != NULL)
HDfree(tv_ptr->large_ds_buf_2);
if (tv_ptr->large_ds_slice_buf != NULL)
HDfree(tv_ptr->large_ds_slice_buf);
return;
} /* hs_dr_pio_test__takedown() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test__d2m_l2s()
*
* Purpose: Part one of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can read from disk correctly using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* In this function, we test this by reading small_rank - 1
* slices from the on disk large cube, and verifying that the
* data read is correct. Verify that H5Sselect_shape_same()
* returns true on the memory and file selections.
*
* Return: void
*
* Programmer: JRM -- 9/10/11
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG 0
static void
contig_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
const char *fcnName = "contig_hs_dr_pio_test__run_test()";
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
hbool_t mis_match = FALSE;
int i, j, k, l;
size_t n;
int mpi_rank; /* needed by the VRFY macro */
uint32_t expected_value;
uint32_t *ptr_1;
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* We have already done a H5Sselect_all() on the dataspace
* small_ds_slice_sid in the initialization phase, so no need to
* call H5Sselect_all() again.
*/
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read slices of the large cube.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* zero out the buffer we will be reading into */
HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
#if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s reading slices from big cube on disk into small cube slice.\n", fcnName);
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
/* in serial versions of this test, we loop through all the dimensions
* of the large data set. However, in the parallel version, each
* process only works with that slice of the large cube indicated
* by its rank -- hence we set the most slowly changing index to
* mpi_rank, and don't iterate over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank - 1 >= 1 and that
* large_rank > small_rank by the assertions at the head
* of this function. Thus no need for another inner loop.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0, H5S_SELECT_SET, tv_ptr->start_ptr,
tv_ptr->stride_ptr, tv_ptr->count_ptr, tv_ptr->block_ptr);
VRFY((ret != FAIL), "H5Sselect_hyperslab(file_large_cube_sid) succeeded");
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->small_ds_slice_sid, tv_ptr->file_large_ds_sid_0);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* Read selection from disk */
#if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, (int)(tv_ptr->mpi_rank),
(int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]), (int)(tv_ptr->start[2]),
(int)(tv_ptr->start[3]), (int)(tv_ptr->start[4]));
HDfprintf(stdout, "%s slice/file extent dims = %d/%d.\n", fcnName,
H5Sget_simple_extent_ndims(tv_ptr->small_ds_slice_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
ret =
H5Dread(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->small_ds_slice_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_slice_buf);
VRFY((ret >= 0), "H5Dread() slice from large ds succeeded.");
/* verify that expected data is retrieved */
mis_match = FALSE;
ptr_1 = tv_ptr->small_ds_slice_buf;
expected_value =
(uint32_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
for (n = 0; n < tv_ptr->small_ds_slice_size; n++) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
*ptr_1 = 0; /* zero data for next use */
ptr_1++;
expected_value++;
}
VRFY((mis_match == FALSE), "small slice read from large ds data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* contig_hs_dr_pio_test__d2m_l2s() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test__d2m_s2l()
*
* Purpose: Part two of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can read from disk correctly using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* In this function, we test this by reading slices of the
* on disk small data set into slices through the in memory
* large data set, and verify that the correct data (and
* only the correct data) is read.
*
* Return: void
*
* Programmer: JRM -- 8/10/11
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG 0
static void
contig_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
const char *fcnName = "contig_hs_dr_pio_test__d2m_s2l()";
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
hbool_t mis_match = FALSE;
int i, j, k, l;
size_t n;
int mpi_rank; /* needed by the VRFY macro */
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* Read slices of the on disk small data set into slices
* through the in memory large data set, and verify that the correct
* data (and only the correct data) is read.
*/
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) succeeded");
#if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
HDfprintf(stdout, "%s reading slices of on disk small data set into slices of big data set.\n", fcnName);
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
/* zero out the in memory large ds */
HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read slices of the large cube.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* in serial versions of this test, we loop through all the dimensions
* of the large data set that don't appear in the small data set.
*
* However, in the parallel version, each process only works with that
* slice of the large (and small) data set indicated by its rank -- hence
* we set the most slowly changing index to mpi_rank, and don't iterate
* over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, H5S_SELECT_SET, tv_ptr->start_ptr,
tv_ptr->stride_ptr, tv_ptr->count_ptr, tv_ptr->block_ptr);
VRFY((ret != FAIL), "H5Sselect_hyperslab(mem_large_ds_sid) succeeded");
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* Read selection from disk */
#if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, (int)(tv_ptr->mpi_rank),
(int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]), (int)(tv_ptr->start[2]),
(int)(tv_ptr->start[3]), (int)(tv_ptr->start[4]));
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
#endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
ret = H5Dread(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_1);
VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
/* verify that the expected data and only the
* expected data was read.
*/
ptr_1 = tv_ptr->large_ds_buf_1;
expected_value = (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
start_index =
(size_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
HDassert(start_index < stop_index);
HDassert(stop_index <= tv_ptr->large_ds_size);
for (n = 0; n < tv_ptr->large_ds_size; n++) {
if ((n >= start_index) && (n <= stop_index)) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
expected_value++;
}
else {
if (*ptr_1 != 0) {
mis_match = TRUE;
}
}
/* zero out the value for the next pass */
*ptr_1 = 0;
ptr_1++;
}
VRFY((mis_match == FALSE), "small slice read from large ds data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* contig_hs_dr_pio_test__d2m_s2l() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test__m2d_l2s()
*
* Purpose: Part three of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can write from memory to file using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* Do this by writing small_rank - 1 dimensional slices from
* the in memory large data set to the on disk small cube
* dataset. After each write, read the slice of the small
* dataset back from disk, and verify that it contains
* the expected data. Verify that H5Sselect_shape_same()
* returns true on the memory and file selections.
*
* Return: void
*
* Programmer: JRM -- 8/10/11
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG 0
static void
contig_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
const char *fcnName = "contig_hs_dr_pio_test__m2d_l2s()";
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
hbool_t mis_match = FALSE;
int i, j, k, l;
size_t n;
int mpi_rank; /* needed by the VRFY macro */
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* now we go in the opposite direction, verifying that we can write
* from memory to file using selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* Start by writing small_rank - 1 dimensional slices from the in memory large
* data set to the on disk small cube dataset. After each write, read the
* slice of the small dataset back from disk, and verify that it contains
* the expected data. Verify that H5Sselect_shape_same() returns true on
* the memory and file selections.
*/
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) succeeded");
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read slices of the large cube.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* zero out the in memory small ds */
HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
#if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
HDfprintf(stdout, "%s writing slices from big ds to slices of small ds on disk.\n", fcnName);
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
/* in serial versions of this test, we loop through all the dimensions
* of the large data set that don't appear in the small data set.
*
* However, in the parallel version, each process only works with that
* slice of the large (and small) data set indicated by its rank -- hence
* we set the most slowly changing index to mpi_rank, and don't iterate
* over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
j = 0;
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
/* zero out this rank's slice of the on disk small data set */
ret = H5Dwrite(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_2);
VRFY((ret >= 0), "H5Dwrite() zero slice to small ds succeeded.");
/* select the portion of the in memory large cube from which we
* are going to write data.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, H5S_SELECT_SET, tv_ptr->start_ptr,
tv_ptr->stride_ptr, tv_ptr->count_ptr, tv_ptr->block_ptr);
VRFY((ret >= 0), "H5Sselect_hyperslab() mem_large_ds_sid succeeded.");
/* verify that H5Sselect_shape_same() reports the in
* memory slice through the cube selection and the
* on disk full square selections as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed.");
/* write the slice from the in memory large data set to the
* slice of the on disk small dataset. */
#if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, (int)(tv_ptr->mpi_rank),
(int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]), (int)(tv_ptr->start[2]),
(int)(tv_ptr->start[3]), (int)(tv_ptr->start[4]));
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
ret = H5Dwrite(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_0);
VRFY((ret >= 0), "H5Dwrite() slice to large ds succeeded.");
/* read the on disk square into memory */
ret = H5Dread(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_1);
VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
/* verify that expected data is retrieved */
mis_match = FALSE;
ptr_1 = tv_ptr->small_ds_buf_1;
expected_value =
(uint32_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
start_index = (size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size;
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
HDassert(start_index < stop_index);
HDassert(stop_index <= tv_ptr->small_ds_size);
for (n = 0; n < tv_ptr->small_ds_size; n++) {
if ((n >= start_index) && (n <= stop_index)) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
expected_value++;
}
else {
if (*ptr_1 != 0) {
mis_match = TRUE;
}
}
/* zero out the value for the next pass */
*ptr_1 = 0;
ptr_1++;
}
VRFY((mis_match == FALSE), "small slice write from large ds data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* contig_hs_dr_pio_test__m2d_l2s() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test__m2d_s2l()
*
* Purpose: Part four of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can write from memory to file using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* Do this by writing the contents of the process's slice of
* the in memory small data set to slices of the on disk
* large data set. After each write, read the process's
* slice of the large data set back into memory, and verify
* that it contains the expected data.
*
* Verify that H5Sselect_shape_same() returns true on the
* memory and file selections.
*
* Return: void
*
* Programmer: JRM -- 8/10/11
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG 0
static void
contig_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
const char *fcnName = "contig_hs_dr_pio_test__m2d_s2l()";
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
hbool_t mis_match = FALSE;
int i, j, k, l;
size_t n;
int mpi_rank; /* needed by the VRFY macro */
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* Now write the contents of the process's slice of the in memory
* small data set to slices of the on disk large data set. After
* each write, read the process's slice of the large data set back
* into memory, and verify that it contains the expected data.
* Verify that H5Sselect_shape_same() returns true on the memory
* and file selections.
*/
/* select the slice of the in memory small data set associated with
* the process's mpi rank.
*/
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) succeeded");
/* set up start, stride, count, and block -- note that we will
* change start[] so as to write slices of the small data set to
* slices of the large data set.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* zero out the in memory large ds */
HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
#if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
HDfprintf(stdout, "%s writing process slices of small ds to slices of large ds on disk.\n", fcnName);
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
#if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
HDfprintf(stdout, "%s:%d: skipping test with start = %d %d %d %d %d.\n", fcnName,
(int)(tv_ptr->mpi_rank), (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
(int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]), (int)(tv_ptr->start[4]));
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
/* Zero out this processes slice of the on disk large data set.
* Note that this will leave one slice with its original data
* as there is one more slice than processes.
*/
ret = H5Dwrite(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->large_ds_slice_sid,
tv_ptr->file_large_ds_process_slice_sid, tv_ptr->xfer_plist,
tv_ptr->large_ds_buf_2);
VRFY((ret != FAIL), "H5Dwrite() to zero large ds succeeded");
/* select the portion of the in memory large cube to which we
* are going to write data.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0, H5S_SELECT_SET, tv_ptr->start_ptr,
tv_ptr->stride_ptr, tv_ptr->count_ptr, tv_ptr->block_ptr);
VRFY((ret != FAIL), "H5Sselect_hyperslab() target large ds slice succeeded");
/* verify that H5Sselect_shape_same() reports the in
* memory small data set slice selection and the
* on disk slice through the large data set selection
* as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->mem_small_ds_sid, tv_ptr->file_large_ds_sid_0);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* write the small data set slice from memory to the
* target slice of the disk data set
*/
#if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, (int)(tv_ptr->mpi_rank),
(int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]), (int)(tv_ptr->start[2]),
(int)(tv_ptr->start[3]), (int)(tv_ptr->start[4]));
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
ret = H5Dwrite(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_0);
VRFY((ret != FAIL), "H5Dwrite of small ds slice to large ds succeeded");
/* read this processes slice on the on disk large
* data set into memory.
*/
ret = H5Dread(
tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_process_slice_sid,
tv_ptr->file_large_ds_process_slice_sid, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_1);
VRFY((ret != FAIL), "H5Dread() of process slice of large ds succeeded");
/* verify that the expected data and only the
* expected data was read.
*/
ptr_1 = tv_ptr->large_ds_buf_1;
expected_value = (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
start_index =
(size_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
HDassert(start_index < stop_index);
HDassert(stop_index < tv_ptr->large_ds_size);
for (n = 0; n < tv_ptr->large_ds_size; n++) {
if ((n >= start_index) && (n <= stop_index)) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
expected_value++;
}
else {
if (*ptr_1 != 0) {
mis_match = TRUE;
}
}
/* zero out buffer for next test */
*ptr_1 = 0;
ptr_1++;
}
VRFY((mis_match == FALSE), "small ds slice write to large ds slice data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* contig_hs_dr_pio_test__m2d_s2l() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test__run_test()
*
* Purpose: Test I/O to/from hyperslab selections of different rank in
* the parallel.
*
* Return: void
*
* Programmer: JRM -- 9/18/09
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG 0
static void
contig_hs_dr_pio_test__run_test(const int test_num, const int edge_size, const int chunk_edge_size,
const int small_rank, const int large_rank, const hbool_t use_collective_io,
const hid_t dset_type, int express_test, int *skips_ptr, int max_skips,
int64_t *total_tests_ptr, int64_t *tests_run_ptr, int64_t *tests_skipped_ptr,
int mpi_rank)
{
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
const char *fcnName = "contig_hs_dr_pio_test__run_test()";
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
struct hs_dr_pio_test_vars_t test_vars = {
/* int mpi_size = */ -1,
/* int mpi_rank = */ -1,
/* MPI_Comm mpi_comm = */ MPI_COMM_NULL,
/* MPI_Inf mpi_info = */ MPI_INFO_NULL,
/* int test_num = */ -1,
/* int edge_size = */ -1,
/* int checker_edge_size = */ -1,
/* int chunk_edge_size = */ -1,
/* int small_rank = */ -1,
/* int large_rank = */ -1,
/* hid_t dset_type = */ -1,
/* uint32_t * small_ds_buf_0 = */ NULL,
/* uint32_t * small_ds_buf_1 = */ NULL,
/* uint32_t * small_ds_buf_2 = */ NULL,
/* uint32_t * small_ds_slice_buf = */ NULL,
/* uint32_t * large_ds_buf_0 = */ NULL,
/* uint32_t * large_ds_buf_1 = */ NULL,
/* uint32_t * large_ds_buf_2 = */ NULL,
/* uint32_t * large_ds_slice_buf = */ NULL,
/* int small_ds_offset = */ -1,
/* int large_ds_offset = */ -1,
/* hid_t fid = */ -1, /* HDF5 file ID */
/* hid_t xfer_plist = */ H5P_DEFAULT,
/* hid_t full_mem_small_ds_sid = */ -1,
/* hid_t full_file_small_ds_sid = */ -1,
/* hid_t mem_small_ds_sid = */ -1,
/* hid_t file_small_ds_sid_0 = */ -1,
/* hid_t file_small_ds_sid_1 = */ -1,
/* hid_t small_ds_slice_sid = */ -1,
/* hid_t full_mem_large_ds_sid = */ -1,
/* hid_t full_file_large_ds_sid = */ -1,
/* hid_t mem_large_ds_sid = */ -1,
/* hid_t file_large_ds_sid_0 = */ -1,
/* hid_t file_large_ds_sid_1 = */ -1,
/* hid_t file_large_ds_process_slice_sid = */ -1,
/* hid_t mem_large_ds_process_slice_sid = */ -1,
/* hid_t large_ds_slice_sid = */ -1,
/* hid_t small_dataset = */ -1, /* Dataset ID */
/* hid_t large_dataset = */ -1, /* Dataset ID */
/* size_t small_ds_size = */ 1,
/* size_t small_ds_slice_size = */ 1,
/* size_t large_ds_size = */ 1,
/* size_t large_ds_slice_size = */ 1,
/* hsize_t dims[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t chunk_dims[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t start[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t stride[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t count[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t block[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t * start_ptr = */ NULL,
/* hsize_t * stride_ptr = */ NULL,
/* hsize_t * count_ptr = */ NULL,
/* hsize_t * block_ptr = */ NULL,
/* int skips = */ 0,
/* int max_skips = */ 0,
/* int64_t total_tests = */ 0,
/* int64_t tests_run = */ 0,
/* int64_t tests_skipped = */ 0};
struct hs_dr_pio_test_vars_t *tv_ptr = &test_vars;
if (MAINPROCESS)
printf("\r - running test #%lld: small rank = %d, large rank = %d", (long long)(test_num + 1),
small_rank, large_rank);
hs_dr_pio_test__setup(test_num, edge_size, -1, chunk_edge_size, small_rank, large_rank, use_collective_io,
dset_type, express_test, tv_ptr);
/* initialize skips & max_skips */
tv_ptr->skips = *skips_ptr;
tv_ptr->max_skips = max_skips;
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: small rank = %d, large rank = %d.\n", test_num, small_rank, large_rank);
HDfprintf(stdout, "test %d: Initialization complete.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
/* first, verify that we can read from disk correctly using selections
* of different rank that H5Sselect_shape_same() views as being of the
* same shape.
*
* Start by reading small_rank - 1 dimensional slice from the on disk
* large cube, and verifying that the data read is correct. Verify that
* H5Sselect_shape_same() returns true on the memory and file selections.
*/
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__d2m_l2s.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
contig_hs_dr_pio_test__d2m_l2s(tv_ptr);
/* Second, read slices of the on disk small data set into slices
* through the in memory large data set, and verify that the correct
* data (and only the correct data) is read.
*/
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__d2m_s2l.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
contig_hs_dr_pio_test__d2m_s2l(tv_ptr);
/* now we go in the opposite direction, verifying that we can write
* from memory to file using selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* Start by writing small_rank - 1 D slices from the in memory large data
* set to the on disk small cube dataset. After each write, read the
* slice of the small dataset back from disk, and verify that it contains
* the expected data. Verify that H5Sselect_shape_same() returns true on
* the memory and file selections.
*/
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__m2d_l2s.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
contig_hs_dr_pio_test__m2d_l2s(tv_ptr);
/* Now write the contents of the process's slice of the in memory
* small data set to slices of the on disk large data set. After
* each write, read the process's slice of the large data set back
* into memory, and verify that it contains the expected data.
* Verify that H5Sselect_shape_same() returns true on the memory
* and file selections.
*/
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__m2d_s2l.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
contig_hs_dr_pio_test__m2d_s2l(tv_ptr);
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: Subtests complete -- tests run/skipped/total = %lld/%lld/%lld.\n",
test_num, (long long)(tv_ptr->tests_run), (long long)(tv_ptr->tests_skipped),
(long long)(tv_ptr->total_tests));
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
hs_dr_pio_test__takedown(tv_ptr);
#if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: Takedown complete.\n", test_num);
}
#endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
*skips_ptr = tv_ptr->skips;
*total_tests_ptr += tv_ptr->total_tests;
*tests_run_ptr += tv_ptr->tests_run;
*tests_skipped_ptr += tv_ptr->tests_skipped;
return;
} /* contig_hs_dr_pio_test__run_test() */
/*-------------------------------------------------------------------------
* Function: contig_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
*
* Purpose: Test I/O to/from hyperslab selections of different rank in
* the parallel case.
*
* Return: void
*
* Programmer: JRM -- 9/18/09
*
*-------------------------------------------------------------------------
*/
#define CONTIG_HS_DR_PIO_TEST__DEBUG 0
static void
contig_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
{
int express_test;
int local_express_test;
int mpi_rank = -1;
int mpi_size;
int test_num = 0;
int edge_size;
int chunk_edge_size = 0;
int small_rank;
int large_rank;
int mpi_result;
int skips = 0;
int max_skips = 0;
/* The following table list the number of sub-tests skipped between
* each test that is actually executed as a function of the express
* test level. Note that any value in excess of 4880 will cause all
* sub tests to be skipped.
*/
int max_skips_tbl[4] = {0, 4, 64, 1024};
hid_t dset_type = H5T_NATIVE_UINT;
int64_t total_tests = 0;
int64_t tests_run = 0;
int64_t tests_skipped = 0;
HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned));
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
edge_size = (mpi_size > 6 ? mpi_size : 6);
local_express_test = EXPRESS_MODE; /* GetTestExpress(); */
mpi_result = MPI_Allreduce((void *)&local_express_test, (void *)&express_test, 1, MPI_INT, MPI_MAX,
MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "MPI_Allreduce(0) succeeded");
if (local_express_test < 0) {
max_skips = max_skips_tbl[0];
}
else if (local_express_test > 3) {
max_skips = max_skips_tbl[3];
}
else {
max_skips = max_skips_tbl[local_express_test];
}
for (large_rank = 3; large_rank <= PAR_SS_DR_MAX_RANK; large_rank++) {
for (small_rank = 2; small_rank < large_rank; small_rank++) {
switch (sstest_type) {
case IND_CONTIG:
/* contiguous data set, independent I/O */
chunk_edge_size = 0;
contig_hs_dr_pio_test__run_test(
test_num, edge_size, chunk_edge_size, small_rank, large_rank, FALSE, dset_type,
express_test, &skips, max_skips, &total_tests, &tests_run, &tests_skipped, mpi_rank);
test_num++;
break;
/* end of case IND_CONTIG */
case COL_CONTIG:
/* contiguous data set, collective I/O */
chunk_edge_size = 0;
contig_hs_dr_pio_test__run_test(
test_num, edge_size, chunk_edge_size, small_rank, large_rank, TRUE, dset_type,
express_test, &skips, max_skips, &total_tests, &tests_run, &tests_skipped, mpi_rank);
test_num++;
break;
/* end of case COL_CONTIG */
case IND_CHUNKED:
/* chunked data set, independent I/O */
chunk_edge_size = 5;
contig_hs_dr_pio_test__run_test(
test_num, edge_size, chunk_edge_size, small_rank, large_rank, FALSE, dset_type,
express_test, &skips, max_skips, &total_tests, &tests_run, &tests_skipped, mpi_rank);
test_num++;
break;
/* end of case IND_CHUNKED */
case COL_CHUNKED:
/* chunked data set, collective I/O */
chunk_edge_size = 5;
contig_hs_dr_pio_test__run_test(
test_num, edge_size, chunk_edge_size, small_rank, large_rank, TRUE, dset_type,
express_test, &skips, max_skips, &total_tests, &tests_run, &tests_skipped, mpi_rank);
test_num++;
break;
/* end of case COL_CHUNKED */
default:
VRFY((FALSE), "unknown test type");
break;
} /* end of switch(sstest_type) */
#if CONTIG_HS_DR_PIO_TEST__DEBUG
if ((MAINPROCESS) && (tests_skipped > 0)) {
HDfprintf(stdout, " run/skipped/total = %lld/%lld/%lld.\n", tests_run, tests_skipped,
total_tests);
}
#endif /* CONTIG_HS_DR_PIO_TEST__DEBUG */
}
}
if (MAINPROCESS) {
if (tests_skipped > 0) {
HDfprintf(stdout, " %" PRId64 " of %" PRId64 " subtests skipped to expedite testing.\n",
tests_skipped, total_tests);
}
else
HDprintf("\n");
}
return;
} /* contig_hs_dr_pio_test() */
/****************************************************************
**
** ckrbrd_hs_dr_pio_test__slct_ckrbrd():
** Given a dataspace of tgt_rank, and dimensions:
**
** (mpi_size + 1), edge_size, ... , edge_size
**
** edge_size, and a checker_edge_size, select a checker
** board selection of a sel_rank (sel_rank < tgt_rank)
** dimensional slice through the dataspace parallel to the
** sel_rank fastest changing indices, with origin (in the
** higher indices) as indicated by the start array.
**
** Note that this function, like all its relatives, is
** hard coded to presume a maximum dataspace rank of 5.
** While this maximum is declared as a constant, increasing
** it will require extensive coding in addition to changing
** the value of the constant.
**
** JRM -- 10/8/09
**
****************************************************************/
#define CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__slct_ckrbrd(const int mpi_rank, const hid_t tgt_sid, const int tgt_rank,
const int edge_size, const int checker_edge_size, const int sel_rank,
hsize_t sel_start[])
{
#if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__slct_ckrbrd():";
#endif
hbool_t first_selection = TRUE;
int i, j, k, l, m;
int n_cube_offset;
int sel_offset;
const int test_max_rank = PAR_SS_DR_MAX_RANK; /* must update code if */
/* this changes */
hsize_t base_count;
hsize_t offset_count;
hsize_t start[PAR_SS_DR_MAX_RANK];
hsize_t stride[PAR_SS_DR_MAX_RANK];
hsize_t count[PAR_SS_DR_MAX_RANK];
hsize_t block[PAR_SS_DR_MAX_RANK];
herr_t ret; /* Generic return value */
HDassert(edge_size >= 6);
HDassert(0 < checker_edge_size);
HDassert(checker_edge_size <= edge_size);
HDassert(0 < sel_rank);
HDassert(sel_rank <= tgt_rank);
HDassert(tgt_rank <= test_max_rank);
HDassert(test_max_rank <= PAR_SS_DR_MAX_RANK);
sel_offset = test_max_rank - sel_rank;
HDassert(sel_offset >= 0);
n_cube_offset = test_max_rank - tgt_rank;
HDassert(n_cube_offset >= 0);
HDassert(n_cube_offset <= sel_offset);
#if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
HDfprintf(stdout, "%s:%d: edge_size/checker_edge_size = %d/%d\n", fcnName, mpi_rank, edge_size,
checker_edge_size);
HDfprintf(stdout, "%s:%d: sel_rank/sel_offset = %d/%d.\n", fcnName, mpi_rank, sel_rank, sel_offset);
HDfprintf(stdout, "%s:%d: tgt_rank/n_cube_offset = %d/%d.\n", fcnName, mpi_rank, tgt_rank, n_cube_offset);
#endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
/* First, compute the base count (which assumes start == 0
* for the associated offset) and offset_count (which
* assumes start == checker_edge_size for the associated
* offset).
*
* Note that the following computation depends on the C99
* requirement that integer division discard any fraction
* (truncation towards zero) to function correctly. As we
* now require C99, this shouldn't be a problem, but noting
* it may save us some pain if we are ever obliged to support
* pre-C99 compilers again.
*/
base_count = (hsize_t)(edge_size / (checker_edge_size * 2));
if ((edge_size % (checker_edge_size * 2)) > 0) {
base_count++;
}
offset_count = (hsize_t)((edge_size - checker_edge_size) / (checker_edge_size * 2));
if (((edge_size - checker_edge_size) % (checker_edge_size * 2)) > 0) {
offset_count++;
}
/* Now set up the stride and block arrays, and portions of the start
* and count arrays that will not be altered during the selection of
* the checker board.
*/
i = 0;
while (i < n_cube_offset) {
/* these values should never be used */
start[i] = 0;
stride[i] = 0;
count[i] = 0;
block[i] = 0;
i++;
}
while (i < sel_offset) {
start[i] = sel_start[i];
stride[i] = (hsize_t)(2 * edge_size);
count[i] = 1;
block[i] = 1;
i++;
}
while (i < test_max_rank) {
stride[i] = (hsize_t)(2 * checker_edge_size);
block[i] = (hsize_t)checker_edge_size;
i++;
}
i = 0;
do {
if (0 >= sel_offset) {
if (i == 0) {
start[0] = 0;
count[0] = base_count;
}
else {
start[0] = (hsize_t)checker_edge_size;
count[0] = offset_count;
}
}
j = 0;
do {
if (1 >= sel_offset) {
if (j == 0) {
start[1] = 0;
count[1] = base_count;
}
else {
start[1] = (hsize_t)checker_edge_size;
count[1] = offset_count;
}
}
k = 0;
do {
if (2 >= sel_offset) {
if (k == 0) {
start[2] = 0;
count[2] = base_count;
}
else {
start[2] = (hsize_t)checker_edge_size;
count[2] = offset_count;
}
}
l = 0;
do {
if (3 >= sel_offset) {
if (l == 0) {
start[3] = 0;
count[3] = base_count;
}
else {
start[3] = (hsize_t)checker_edge_size;
count[3] = offset_count;
}
}
m = 0;
do {
if (4 >= sel_offset) {
if (m == 0) {
start[4] = 0;
count[4] = base_count;
}
else {
start[4] = (hsize_t)checker_edge_size;
count[4] = offset_count;
}
}
if (((i + j + k + l + m) % 2) == 0) {
#if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
HDfprintf(stdout, "%s%d: *** first_selection = %d ***\n", fcnName, mpi_rank,
(int)first_selection);
HDfprintf(stdout, "%s:%d: i/j/k/l/m = %d/%d/%d/%d/%d\n", fcnName, mpi_rank, i, j,
k, l, m);
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)start[0], (int)start[1], (int)start[2], (int)start[3],
(int)start[4]);
HDfprintf(stdout, "%s:%d: stride = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)stride[0], (int)stride[1], (int)stride[2], (int)stride[3],
(int)stride[4]);
HDfprintf(stdout, "%s:%d: count = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)count[0], (int)count[1], (int)count[2], (int)count[3],
(int)count[4]);
HDfprintf(stdout, "%s:%d: block = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)block[0], (int)block[1], (int)block[2], (int)block[3],
(int)block[4]);
HDfprintf(stdout, "%s:%d: n-cube extent dims = %d.\n", fcnName, mpi_rank,
H5Sget_simple_extent_ndims(tgt_sid));
HDfprintf(stdout, "%s:%d: selection rank = %d.\n", fcnName, mpi_rank, sel_rank);
#endif
if (first_selection) {
first_selection = FALSE;
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_SET, &(start[n_cube_offset]),
&(stride[n_cube_offset]), &(count[n_cube_offset]),
&(block[n_cube_offset]));
VRFY((ret != FAIL), "H5Sselect_hyperslab(SET) succeeded");
}
else {
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_OR, &(start[n_cube_offset]),
&(stride[n_cube_offset]), &(count[n_cube_offset]),
&(block[n_cube_offset]));
VRFY((ret != FAIL), "H5Sselect_hyperslab(OR) succeeded");
}
}
m++;
} while ((m <= 1) && (4 >= sel_offset));
l++;
} while ((l <= 1) && (3 >= sel_offset));
k++;
} while ((k <= 1) && (2 >= sel_offset));
j++;
} while ((j <= 1) && (1 >= sel_offset));
i++;
} while ((i <= 1) && (0 >= sel_offset));
#if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(tgt_sid));
#endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
/* Clip the selection back to the dataspace proper. */
for (i = 0; i < test_max_rank; i++) {
start[i] = 0;
stride[i] = (hsize_t)edge_size;
count[i] = 1;
block[i] = (hsize_t)edge_size;
}
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_AND, start, stride, count, block);
VRFY((ret != FAIL), "H5Sselect_hyperslab(AND) succeeded");
#if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(tgt_sid));
HDfprintf(stdout, "%s%d: done.\n", fcnName, mpi_rank);
#endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
return;
} /* ckrbrd_hs_dr_pio_test__slct_ckrbrd() */
/****************************************************************
**
** ckrbrd_hs_dr_pio_test__verify_data():
**
** Examine the supplied buffer to see if it contains the
** expected data. Return TRUE if it does, and FALSE
** otherwise.
**
** The supplied buffer is presumed to this process's slice
** of the target data set. Each such slice will be an
** n-cube of rank (rank -1) and the supplied edge_size with
** origin (mpi_rank, 0, ... , 0) in the target data set.
**
** Further, the buffer is presumed to be the result of reading
** or writing a checker board selection of an m (1 <= m <
** rank) dimensional slice through this processes slice
** of the target data set. Also, this slice must be parallel
** to the fastest changing indices.
**
** It is further presumed that the buffer was zeroed before
** the read/write, and that the full target data set (i.e.
** the buffer/data set for all processes) was initialized
** with the natural numbers listed in order from the origin
** along the fastest changing axis.
**
** Thus for a 20x10x10 dataset, the value stored in location
** (x, y, z) (assuming that z is the fastest changing index
** and x the slowest) is assumed to be:
**
** (10 * 10 * x) + (10 * y) + z
**
** Further, supposing that this is process 10, this process's
** slice of the dataset would be a 10 x 10 2-cube with origin
** (10, 0, 0) in the data set, and would be initialize (prior
** to the checkerboard selection) as follows:
**
** 1000, 1001, 1002, ... 1008, 1009
** 1010, 1011, 1012, ... 1018, 1019
** . . . . .
** . . . . .
** . . . . .
** 1090, 1091, 1092, ... 1098, 1099
**
** In the case of a read from the processors slice of another
** data set of different rank, the values expected will have
** to be adjusted accordingly. This is done via the
** first_expected_val parameter.
**
** Finally, the function presumes that the first element
** of the buffer resides either at the origin of either
** a selected or an unselected checker. (Translation:
** if partial checkers appear in the buffer, they will
** intersect the edges of the n-cube opposite the origin.)
**
****************************************************************/
#define CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG 0
static hbool_t
ckrbrd_hs_dr_pio_test__verify_data(uint32_t *buf_ptr, const int rank, const int edge_size,
const int checker_edge_size, uint32_t first_expected_val,
hbool_t buf_starts_in_checker)
{
#if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__verify_data():";
#endif
hbool_t good_data = TRUE;
hbool_t in_checker;
hbool_t start_in_checker[5];
uint32_t expected_value;
uint32_t *val_ptr;
int i, j, k, l, m; /* to track position in n-cube */
int v, w, x, y, z; /* to track position in checker */
const int test_max_rank = 5; /* code changes needed if this is increased */
HDassert(buf_ptr != NULL);
HDassert(0 < rank);
HDassert(rank <= test_max_rank);
HDassert(edge_size >= 6);
HDassert(0 < checker_edge_size);
HDassert(checker_edge_size <= edge_size);
HDassert(test_max_rank <= PAR_SS_DR_MAX_RANK);
#if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
HDfprintf(stdout, "%s mpi_rank = %d.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s rank = %d.\n", fcnName, rank);
HDfprintf(stdout, "%s edge_size = %d.\n", fcnName, edge_size);
HDfprintf(stdout, "%s checker_edge_size = %d.\n", fcnName, checker_edge_size);
HDfprintf(stdout, "%s first_expected_val = %d.\n", fcnName, (int)first_expected_val);
HDfprintf(stdout, "%s starts_in_checker = %d.\n", fcnName, (int)buf_starts_in_checker);
}
#endif
val_ptr = buf_ptr;
expected_value = first_expected_val;
i = 0;
v = 0;
start_in_checker[0] = buf_starts_in_checker;
do {
if (v >= checker_edge_size) {
start_in_checker[0] = !start_in_checker[0];
v = 0;
}
j = 0;
w = 0;
start_in_checker[1] = start_in_checker[0];
do {
if (w >= checker_edge_size) {
start_in_checker[1] = !start_in_checker[1];
w = 0;
}
k = 0;
x = 0;
start_in_checker[2] = start_in_checker[1];
do {
if (x >= checker_edge_size) {
start_in_checker[2] = !start_in_checker[2];
x = 0;
}
l = 0;
y = 0;
start_in_checker[3] = start_in_checker[2];
do {
if (y >= checker_edge_size) {
start_in_checker[3] = !start_in_checker[3];
y = 0;
}
m = 0;
z = 0;
#if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
HDfprintf(stdout, "%d, %d, %d, %d, %d:", i, j, k, l, m);
#endif
in_checker = start_in_checker[3];
do {
#if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
HDfprintf(stdout, " %d", (int)(*val_ptr));
#endif
if (z >= checker_edge_size) {
in_checker = !in_checker;
z = 0;
}
if (in_checker) {
if (*val_ptr != expected_value) {
good_data = FALSE;
}
/* zero out buffer for re-use */
*val_ptr = 0;
}
else if (*val_ptr != 0) {
good_data = FALSE;
/* zero out buffer for re-use */
*val_ptr = 0;
}
val_ptr++;
expected_value++;
m++;
z++;
} while ((rank >= (test_max_rank - 4)) && (m < edge_size));
#if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
HDfprintf(stdout, "\n");
#endif
l++;
y++;
} while ((rank >= (test_max_rank - 3)) && (l < edge_size));
k++;
x++;
} while ((rank >= (test_max_rank - 2)) && (k < edge_size));
j++;
w++;
} while ((rank >= (test_max_rank - 1)) && (j < edge_size));
i++;
v++;
} while ((rank >= test_max_rank) && (i < edge_size));
return (good_data);
} /* ckrbrd_hs_dr_pio_test__verify_data() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test__d2m_l2s()
*
* Purpose: Part one of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can read from disk correctly using checker
* board selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* In this function, we test this by reading small_rank - 1
* checker board slices from the on disk large cube, and
* verifying that the data read is correct. Verify that
* H5Sselect_shape_same() returns true on the memory and
* file selections.
*
* Return: void
*
* Programmer: JRM -- 9/15/11
*
*-------------------------------------------------------------------------
*/
#define CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__d2m_l2s()";
uint32_t *ptr_0;
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
hbool_t data_ok = FALSE;
int i, j, k, l;
uint32_t expected_value;
int mpi_rank; /* needed by VRFY */
hsize_t sel_start[PAR_SS_DR_MAX_RANK];
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* first, verify that we can read from disk correctly using selections
* of different rank that H5Sselect_shape_same() views as being of the
* same shape.
*
* Start by reading a (small_rank - 1)-D checker board slice from this
* processes slice of the on disk large data set, and verifying that the
* data read is correct. Verify that H5Sselect_shape_same() returns
* true on the memory and file selections.
*
* The first step is to set up the needed checker board selection in the
* in memory small small cube
*/
sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank, tv_ptr->small_ds_slice_sid, tv_ptr->small_rank - 1,
tv_ptr->edge_size, tv_ptr->checker_edge_size, tv_ptr->small_rank - 1,
sel_start);
/* zero out the buffer we will be reading into */
HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s:%d: initial small_ds_slice_buf = ", fcnName, tv_ptr->mpi_rank);
ptr_0 = tv_ptr->small_ds_slice_buf;
for (i = 0; i < (int)(tv_ptr->small_ds_slice_size); i++) {
HDfprintf(stdout, "%d ", (int)(*ptr_0));
ptr_0++;
}
HDfprintf(stdout, "\n");
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read slices of the large cube.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s:%d: reading slice from big ds on disk into small ds slice.\n", fcnName,
tv_ptr->mpi_rank);
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
/* in serial versions of this test, we loop through all the dimensions
* of the large data set. However, in the parallel version, each
* process only works with that slice of the large cube indicated
* by its rank -- hence we set the most slowly changing index to
* mpi_rank, and don't iterate over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank - 1 >= 1 and that
* large_rank > small_rank by the assertions at the head
* of this function. Thus no need for another inner loop.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
HDassert((tv_ptr->start[0] == 0) || (0 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[1] == 0) || (1 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[2] == 0) || (2 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[3] == 0) || (3 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[4] == 0) || (4 < tv_ptr->small_ds_offset + 1));
ckrbrd_hs_dr_pio_test__slct_ckrbrd(
tv_ptr->mpi_rank, tv_ptr->file_large_ds_sid_0, tv_ptr->large_rank, tv_ptr->edge_size,
tv_ptr->checker_edge_size, tv_ptr->small_rank - 1, tv_ptr->start);
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->small_ds_slice_sid, tv_ptr->file_large_ds_sid_0);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* Read selection from disk */
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, tv_ptr->mpi_rank,
tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2], tv_ptr->start[3],
tv_ptr->start[4]);
HDfprintf(stdout, "%s slice/file extent dims = %d/%d.\n", fcnName,
H5Sget_simple_extent_ndims(tv_ptr->small_ds_slice_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
ret =
H5Dread(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->small_ds_slice_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_slice_buf);
VRFY((ret >= 0), "H5Dread() slice from large ds succeeded.");
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
HDfprintf(stdout, "%s:%d: H5Dread() returns.\n", fcnName, tv_ptr->mpi_rank);
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
/* verify that expected data is retrieved */
expected_value =
(uint32_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
data_ok = ckrbrd_hs_dr_pio_test__verify_data(
tv_ptr->small_ds_slice_buf, tv_ptr->small_rank - 1, tv_ptr->edge_size,
tv_ptr->checker_edge_size, expected_value, (hbool_t)TRUE);
VRFY((data_ok == TRUE), "small slice read from large ds data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* ckrbrd_hs_dr_pio_test__d2m_l2s() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test__d2m_s2l()
*
* Purpose: Part two of a series of tests of I/O to/from hyperslab
* selections of different rank in the parallel.
*
* Verify that we can read from disk correctly using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* In this function, we test this by reading checker board
* slices of the on disk small data set into slices through
* the in memory large data set, and verify that the correct
* data (and only the correct data) is read.
*
* Return: void
*
* Programmer: JRM -- 8/15/11
*
*-------------------------------------------------------------------------
*/
#define CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__d2m_s2l()";
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
hbool_t data_ok = FALSE;
int i, j, k, l;
size_t u;
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
int mpi_rank; /* needed by VRFY */
hsize_t sel_start[PAR_SS_DR_MAX_RANK];
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* similarly, read slices of the on disk small data set into slices
* through the in memory large data set, and verify that the correct
* data (and only the correct data) is read.
*/
sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank, tv_ptr->file_small_ds_sid_0, tv_ptr->small_rank,
tv_ptr->edge_size, tv_ptr->checker_edge_size, tv_ptr->small_rank - 1,
sel_start);
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
HDfprintf(stdout, "%s reading slices of on disk small data set into slices of big data set.\n", fcnName);
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
/* zero out the buffer we will be reading into */
HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read the slice of the small data set
* into different slices of the process slice of the large data
* set.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* in serial versions of this test, we loop through all the dimensions
* of the large data set that don't appear in the small data set.
*
* However, in the parallel version, each process only works with that
* slice of the large (and small) data set indicated by its rank -- hence
* we set the most slowly changing index to mpi_rank, and don't iterate
* over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
HDassert((tv_ptr->start[0] == 0) || (0 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[1] == 0) || (1 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[2] == 0) || (2 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[3] == 0) || (3 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[4] == 0) || (4 < tv_ptr->small_ds_offset + 1));
ckrbrd_hs_dr_pio_test__slct_ckrbrd(
tv_ptr->mpi_rank, tv_ptr->mem_large_ds_sid, tv_ptr->large_rank, tv_ptr->edge_size,
tv_ptr->checker_edge_size, tv_ptr->small_rank - 1, tv_ptr->start);
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* Read selection from disk */
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, tv_ptr->mpi_rank,
tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2], tv_ptr->start[3],
tv_ptr->start[4]);
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->large_ds_slice_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
ret = H5Dread(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_1);
VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
/* verify that the expected data and only the
* expected data was read.
*/
data_ok = TRUE;
ptr_1 = tv_ptr->large_ds_buf_1;
expected_value = (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
start_index =
(size_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
#if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
{
int m, n;
HDfprintf(stdout, "%s:%d: expected_value = %d.\n", fcnName, tv_ptr->mpi_rank,
expected_value);
HDfprintf(stdout, "%s:%d: start/stop index = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
start_index, stop_index);
n = 0;
for (m = 0; (unsigned)m < tv_ptr->large_ds_size; m++) {
HDfprintf(stdout, "%d ", (int)(*ptr_1));
ptr_1++;
n++;
if (n >= tv_ptr->edge_size) {
HDfprintf(stdout, "\n");
n = 0;
}
}
HDfprintf(stdout, "\n");
ptr_1 = tv_ptr->large_ds_buf_1;
}
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
HDassert(start_index < stop_index);
HDassert(stop_index <= tv_ptr->large_ds_size);
for (u = 0; u < start_index; u++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
}
/* zero out the value for the next pass */
*ptr_1 = 0;
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from small to large ds data good(1).");
data_ok = ckrbrd_hs_dr_pio_test__verify_data(ptr_1, tv_ptr->small_rank - 1,
tv_ptr->edge_size, tv_ptr->checker_edge_size,
expected_value, (hbool_t)TRUE);
VRFY((data_ok == TRUE), "slice read from small to large ds data good(2).");
ptr_1 = tv_ptr->large_ds_buf_1 + stop_index + 1;
for (u = stop_index + 1; u < tv_ptr->large_ds_size; u++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
}
/* zero out the value for the next pass */
*ptr_1 = 0;
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from small to large ds data good(3).");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* ckrbrd_hs_dr_pio_test__d2m_s2l() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test__m2d_l2s()
*
* Purpose: Part three of a series of tests of I/O to/from checker
* board hyperslab selections of different rank in the
* parallel.
*
* Verify that we can write from memory to file using checker
* board selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* Do this by writing small_rank - 1 dimensional checker
* board slices from the in memory large data set to the on
* disk small cube dataset. After each write, read the
* slice of the small dataset back from disk, and verify
* that it contains the expected data. Verify that
* H5Sselect_shape_same() returns true on the memory and
* file selections.
*
* Return: void
*
* Programmer: JRM -- 8/15/11
*
*-------------------------------------------------------------------------
*/
#define CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__m2d_l2s()";
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
hbool_t data_ok = FALSE;
int i, j, k, l;
size_t u;
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
int mpi_rank; /* needed by VRFY */
hsize_t sel_start[PAR_SS_DR_MAX_RANK];
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* now we go in the opposite direction, verifying that we can write
* from memory to file using selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* Start by writing small_rank - 1 D slices from the in memory large data
* set to the on disk small dataset. After each write, read the slice of
* the small dataset back from disk, and verify that it contains the
* expected data. Verify that H5Sselect_shape_same() returns true on
* the memory and file selections.
*/
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) succeeded");
sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank, tv_ptr->file_small_ds_sid_1, tv_ptr->small_rank,
tv_ptr->edge_size, tv_ptr->checker_edge_size, tv_ptr->small_rank - 1,
sel_start);
/* set up start, stride, count, and block -- note that we will
* change start[] so as to read slices of the large cube.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* zero out the in memory small ds */
HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
HDfprintf(stdout,
"%s writing checker boards selections of slices from big ds to slices of small ds on disk.\n",
fcnName);
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
/* in serial versions of this test, we loop through all the dimensions
* of the large data set that don't appear in the small data set.
*
* However, in the parallel version, each process only works with that
* slice of the large (and small) data set indicated by its rank -- hence
* we set the most slowly changing index to mpi_rank, and don't iterate
* over it.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
j = 0;
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
/* zero out this rank's slice of the on disk small data set */
ret = H5Dwrite(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_2);
VRFY((ret >= 0), "H5Dwrite() zero slice to small ds succeeded.");
/* select the portion of the in memory large cube from which we
* are going to write data.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
HDassert((tv_ptr->start[0] == 0) || (0 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[1] == 0) || (1 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[2] == 0) || (2 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[3] == 0) || (3 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[4] == 0) || (4 < tv_ptr->small_ds_offset + 1));
ckrbrd_hs_dr_pio_test__slct_ckrbrd(
tv_ptr->mpi_rank, tv_ptr->mem_large_ds_sid, tv_ptr->large_rank, tv_ptr->edge_size,
tv_ptr->checker_edge_size, tv_ptr->small_rank - 1, tv_ptr->start);
/* verify that H5Sselect_shape_same() reports the in
* memory checkerboard selection of the slice through the
* large dataset and the checkerboard selection of the process
* slice of the small data set as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->file_small_ds_sid_1, tv_ptr->mem_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed.");
/* write the checker board selection of the slice from the in
* memory large data set to the slice of the on disk small
* dataset.
*/
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, tv_ptr->mpi_rank,
tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2], tv_ptr->start[3],
tv_ptr->start[4]);
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_1));
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
ret = H5Dwrite(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_small_ds_sid_1, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_0);
VRFY((ret >= 0), "H5Dwrite() slice to large ds succeeded.");
/* read the on disk process slice of the small dataset into memory */
ret = H5Dread(tv_ptr->small_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_1);
VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
/* verify that expected data is retrieved */
expected_value =
(uint32_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
start_index = (size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size;
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
HDassert(start_index < stop_index);
HDassert(stop_index <= tv_ptr->small_ds_size);
data_ok = TRUE;
ptr_1 = tv_ptr->small_ds_buf_1;
for (u = 0; u < start_index; u++, ptr_1++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
*ptr_1 = 0;
}
}
data_ok &= ckrbrd_hs_dr_pio_test__verify_data(
tv_ptr->small_ds_buf_1 + start_index, tv_ptr->small_rank - 1, tv_ptr->edge_size,
tv_ptr->checker_edge_size, expected_value, (hbool_t)TRUE);
ptr_1 = tv_ptr->small_ds_buf_1;
for (u = stop_index; u < tv_ptr->small_ds_size; u++, ptr_1++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
*ptr_1 = 0;
}
}
VRFY((data_ok == TRUE), "large slice write slice to small slice data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* ckrbrd_hs_dr_pio_test__m2d_l2s() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test__m2d_s2l()
*
* Purpose: Part four of a series of tests of I/O to/from checker
* board hyperslab selections of different rank in the parallel.
*
* Verify that we can write from memory to file using
* selections of different rank that H5Sselect_shape_same()
* views as being of the same shape.
*
* Do this by writing checker board selections of the contents
* of the process's slice of the in memory small data set to
* slices of the on disk large data set. After each write,
* read the process's slice of the large data set back into
* memory, and verify that it contains the expected data.
*
* Verify that H5Sselect_shape_same() returns true on the
* memory and file selections.
*
* Return: void
*
* Programmer: JRM -- 8/15/11
*
*-------------------------------------------------------------------------
*/
#define CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t *tv_ptr)
{
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__m2d_s2l()";
#endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
hbool_t data_ok = FALSE;
int i, j, k, l;
size_t u;
size_t start_index;
size_t stop_index;
uint32_t expected_value;
uint32_t *ptr_1;
int mpi_rank; /* needed by VRFY */
hsize_t sel_start[PAR_SS_DR_MAX_RANK];
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
/* initialize the local copy of mpi_rank */
mpi_rank = tv_ptr->mpi_rank;
/* Now write the contents of the process's slice of the in memory
* small data set to slices of the on disk large data set. After
* each write, read the process's slice of the large data set back
* into memory, and verify that it contains the expected data.
* Verify that H5Sselect_shape_same() returns true on the memory
* and file selections.
*/
tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
tv_ptr->count[0] = 1;
tv_ptr->block[0] = 1;
for (i = 1; i < tv_ptr->large_rank; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, set) succeeded");
ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, H5S_SELECT_SET, tv_ptr->start, tv_ptr->stride,
tv_ptr->count, tv_ptr->block);
VRFY((ret >= 0), "H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, set) succeeded");
/* setup a checkerboard selection of the slice of the in memory small
* data set associated with the process's mpi rank.
*/
sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank, tv_ptr->mem_small_ds_sid, tv_ptr->small_rank,
tv_ptr->edge_size, tv_ptr->checker_edge_size, tv_ptr->small_rank - 1,
sel_start);
/* set up start, stride, count, and block -- note that we will
* change start[] so as to write checkerboard selections of slices
* of the small data set to slices of the large data set.
*/
for (i = 0; i < PAR_SS_DR_MAX_RANK; i++) {
tv_ptr->start[i] = 0;
tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
tv_ptr->count[i] = 1;
if ((PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1)) {
tv_ptr->block[i] = 1;
}
else {
tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
}
}
/* zero out the in memory large ds */
HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
HDfprintf(stdout,
"%s writing process checkerboard selections of slices of small ds to process slices of large "
"ds on disk.\n",
fcnName);
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0) {
i = tv_ptr->mpi_rank;
}
else {
i = 0;
}
/* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
* loop over it -- either we are setting i to mpi_rank, or
* we are setting it to zero. It will not change during the
* test.
*/
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1) {
j = tv_ptr->mpi_rank;
}
else {
j = 0;
}
do {
if (PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2) {
k = tv_ptr->mpi_rank;
}
else {
k = 0;
}
do {
/* since small rank >= 2 and large_rank > small_rank, we
* have large_rank >= 3. Since PAR_SS_DR_MAX_RANK == 5
* (baring major re-orgaization), this gives us:
*
* (PAR_SS_DR_MAX_RANK - large_rank) <= 2
*
* so no need to repeat the test in the outer loops --
* just set l = 0.
*/
l = 0;
do {
if ((tv_ptr->skips)++ < tv_ptr->max_skips) { /* skip the test */
(tv_ptr->tests_skipped)++;
}
else { /* run the test */
tv_ptr->skips = 0; /* reset the skips counter */
/* we know that small_rank >= 1 and that large_rank > small_rank
* by the assertions at the head of this function. Thus no
* need for another inner loop.
*/
/* Zero out this processes slice of the on disk large data set.
* Note that this will leave one slice with its original data
* as there is one more slice than processes.
*/
ret = H5Dwrite(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_2);
VRFY((ret != FAIL), "H5Dwrite() to zero large ds succeeded");
/* select the portion of the in memory large cube to which we
* are going to write data.
*/
tv_ptr->start[0] = (hsize_t)i;
tv_ptr->start[1] = (hsize_t)j;
tv_ptr->start[2] = (hsize_t)k;
tv_ptr->start[3] = (hsize_t)l;
tv_ptr->start[4] = 0;
HDassert((tv_ptr->start[0] == 0) || (0 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[1] == 0) || (1 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[2] == 0) || (2 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[3] == 0) || (3 < tv_ptr->small_ds_offset + 1));
HDassert((tv_ptr->start[4] == 0) || (4 < tv_ptr->small_ds_offset + 1));
ckrbrd_hs_dr_pio_test__slct_ckrbrd(
tv_ptr->mpi_rank, tv_ptr->file_large_ds_sid_1, tv_ptr->large_rank, tv_ptr->edge_size,
tv_ptr->checker_edge_size, tv_ptr->small_rank - 1, tv_ptr->start);
/* verify that H5Sselect_shape_same() reports the in
* memory small data set slice selection and the
* on disk slice through the large data set selection
* as having the same shape.
*/
check = H5Sselect_shape_same(tv_ptr->mem_small_ds_sid, tv_ptr->file_large_ds_sid_1);
VRFY((check == TRUE), "H5Sselect_shape_same passed");
/* write the small data set slice from memory to the
* target slice of the disk data set
*/
#if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, tv_ptr->mpi_rank,
tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2], tv_ptr->start[3],
tv_ptr->start[4]);
HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n", fcnName, tv_ptr->mpi_rank,
H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_1));
#endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
ret = H5Dwrite(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_small_ds_sid,
tv_ptr->file_large_ds_sid_1, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_0);
VRFY((ret != FAIL), "H5Dwrite of small ds slice to large ds succeeded");
/* read this processes slice on the on disk large
* data set into memory.
*/
ret = H5Dread(tv_ptr->large_dataset, H5T_NATIVE_UINT32, tv_ptr->mem_large_ds_sid,
tv_ptr->file_large_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->large_ds_buf_1);
VRFY((ret != FAIL), "H5Dread() of process slice of large ds succeeded");
/* verify that the expected data and only the
* expected data was read.
*/
expected_value = (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
start_index =
(size_t)((i * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size *
tv_ptr->edge_size) +
(j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
(k * tv_ptr->edge_size * tv_ptr->edge_size) + (l * tv_ptr->edge_size));
stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
HDassert(start_index < stop_index);
HDassert(stop_index < tv_ptr->large_ds_size);
data_ok = TRUE;
ptr_1 = tv_ptr->large_ds_buf_1;
for (u = 0; u < start_index; u++, ptr_1++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
*ptr_1 = 0;
}
}
data_ok &= ckrbrd_hs_dr_pio_test__verify_data(
tv_ptr->large_ds_buf_1 + start_index, tv_ptr->small_rank - 1, tv_ptr->edge_size,
tv_ptr->checker_edge_size, expected_value, (hbool_t)TRUE);
ptr_1 = tv_ptr->large_ds_buf_1;
for (u = stop_index; u < tv_ptr->small_ds_size; u++, ptr_1++) {
if (*ptr_1 != 0) {
data_ok = FALSE;
*ptr_1 = 0;
}
}
VRFY((data_ok == TRUE), "small ds cb slice write to large ds slice data good.");
(tv_ptr->tests_run)++;
}
l++;
(tv_ptr->total_tests)++;
} while ((tv_ptr->large_rank > 2) && ((tv_ptr->small_rank - 1) <= 1) && (l < tv_ptr->edge_size));
k++;
} while ((tv_ptr->large_rank > 3) && ((tv_ptr->small_rank - 1) <= 2) && (k < tv_ptr->edge_size));
j++;
} while ((tv_ptr->large_rank > 4) && ((tv_ptr->small_rank - 1) <= 3) && (j < tv_ptr->edge_size));
return;
} /* ckrbrd_hs_dr_pio_test__m2d_s2l() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test__run_test()
*
* Purpose: Test I/O to/from checkerboard selections of hyperslabs of
* different rank in the parallel.
*
* Return: void
*
* Programmer: JRM -- 10/10/09
*
*-------------------------------------------------------------------------
*/
#define CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG 0
static void
ckrbrd_hs_dr_pio_test__run_test(const int test_num, const int edge_size, const int checker_edge_size,
const int chunk_edge_size, const int small_rank, const int large_rank,
const hbool_t use_collective_io, const hid_t dset_type,
const int express_test, int *skips_ptr, int max_skips,
int64_t *total_tests_ptr, int64_t *tests_run_ptr, int64_t *tests_skipped_ptr,
int mpi_rank)
{
#if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
const char *fcnName = "ckrbrd_hs_dr_pio_test__run_test()";
#endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
struct hs_dr_pio_test_vars_t test_vars = {
/* int mpi_size = */ -1,
/* int mpi_rank = */ -1,
/* MPI_Comm mpi_comm = */ MPI_COMM_NULL,
/* MPI_Inf mpi_info = */ MPI_INFO_NULL,
/* int test_num = */ -1,
/* int edge_size = */ -1,
/* int checker_edge_size = */ -1,
/* int chunk_edge_size = */ -1,
/* int small_rank = */ -1,
/* int large_rank = */ -1,
/* hid_t dset_type = */ -1,
/* uint32_t * small_ds_buf_0 = */ NULL,
/* uint32_t * small_ds_buf_1 = */ NULL,
/* uint32_t * small_ds_buf_2 = */ NULL,
/* uint32_t * small_ds_slice_buf = */ NULL,
/* uint32_t * large_ds_buf_0 = */ NULL,
/* uint32_t * large_ds_buf_1 = */ NULL,
/* uint32_t * large_ds_buf_2 = */ NULL,
/* uint32_t * large_ds_slice_buf = */ NULL,
/* int small_ds_offset = */ -1,
/* int large_ds_offset = */ -1,
/* hid_t fid = */ -1, /* HDF5 file ID */
/* hid_t xfer_plist = */ H5P_DEFAULT,
/* hid_t full_mem_small_ds_sid = */ -1,
/* hid_t full_file_small_ds_sid = */ -1,
/* hid_t mem_small_ds_sid = */ -1,
/* hid_t file_small_ds_sid_0 = */ -1,
/* hid_t file_small_ds_sid_1 = */ -1,
/* hid_t small_ds_slice_sid = */ -1,
/* hid_t full_mem_large_ds_sid = */ -1,
/* hid_t full_file_large_ds_sid = */ -1,
/* hid_t mem_large_ds_sid = */ -1,
/* hid_t file_large_ds_sid_0 = */ -1,
/* hid_t file_large_ds_sid_1 = */ -1,
/* hid_t file_large_ds_process_slice_sid = */ -1,
/* hid_t mem_large_ds_process_slice_sid = */ -1,
/* hid_t large_ds_slice_sid = */ -1,
/* hid_t small_dataset = */ -1, /* Dataset ID */
/* hid_t large_dataset = */ -1, /* Dataset ID */
/* size_t small_ds_size = */ 1,
/* size_t small_ds_slice_size = */ 1,
/* size_t large_ds_size = */ 1,
/* size_t large_ds_slice_size = */ 1,
/* hsize_t dims[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t chunk_dims[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t start[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t stride[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t count[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t block[PAR_SS_DR_MAX_RANK] = */ {0, 0, 0, 0, 0},
/* hsize_t * start_ptr = */ NULL,
/* hsize_t * stride_ptr = */ NULL,
/* hsize_t * count_ptr = */ NULL,
/* hsize_t * block_ptr = */ NULL,
/* int skips = */ 0,
/* int max_skips = */ 0,
/* int64_t total_tests = */ 0,
/* int64_t tests_run = */ 0,
/* int64_t tests_skipped = */ 0};
struct hs_dr_pio_test_vars_t *tv_ptr = &test_vars;
if (MAINPROCESS)
printf("\r - running test #%lld: small rank = %d, large rank = %d", (long long)(test_num + 1),
small_rank, large_rank);
hs_dr_pio_test__setup(test_num, edge_size, checker_edge_size, chunk_edge_size, small_rank, large_rank,
use_collective_io, dset_type, express_test, tv_ptr);
/* initialize skips & max_skips */
tv_ptr->skips = *skips_ptr;
tv_ptr->max_skips = max_skips;
#if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: small rank = %d, large rank = %d.\n", test_num, small_rank, large_rank);
HDfprintf(stdout, "test %d: Initialization complete.\n", test_num);
}
#endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
/* first, verify that we can read from disk correctly using selections
* of different rank that H5Sselect_shape_same() views as being of the
* same shape.
*
* Start by reading a (small_rank - 1)-D slice from this processes slice
* of the on disk large data set, and verifying that the data read is
* correct. Verify that H5Sselect_shape_same() returns true on the
* memory and file selections.
*
* The first step is to set up the needed checker board selection in the
* in memory small small cube
*/
ckrbrd_hs_dr_pio_test__d2m_l2s(tv_ptr);
/* similarly, read slices of the on disk small data set into slices
* through the in memory large data set, and verify that the correct
* data (and only the correct data) is read.
*/
ckrbrd_hs_dr_pio_test__d2m_s2l(tv_ptr);
/* now we go in the opposite direction, verifying that we can write
* from memory to file using selections of different rank that
* H5Sselect_shape_same() views as being of the same shape.
*
* Start by writing small_rank - 1 D slices from the in memory large data
* set to the on disk small dataset. After each write, read the slice of
* the small dataset back from disk, and verify that it contains the
* expected data. Verify that H5Sselect_shape_same() returns true on
* the memory and file selections.
*/
ckrbrd_hs_dr_pio_test__m2d_l2s(tv_ptr);
/* Now write the contents of the process's slice of the in memory
* small data set to slices of the on disk large data set. After
* each write, read the process's slice of the large data set back
* into memory, and verify that it contains the expected data.
* Verify that H5Sselect_shape_same() returns true on the memory
* and file selections.
*/
ckrbrd_hs_dr_pio_test__m2d_s2l(tv_ptr);
#if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: Subtests complete -- tests run/skipped/total = %lld/%lld/%lld.\n",
test_num, (long long)(tv_ptr->tests_run), (long long)(tv_ptr->tests_skipped),
(long long)(tv_ptr->total_tests));
}
#endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
hs_dr_pio_test__takedown(tv_ptr);
#if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
if (MAINPROCESS) {
HDfprintf(stdout, "test %d: Takedown complete.\n", test_num);
}
#endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
*skips_ptr = tv_ptr->skips;
*total_tests_ptr += tv_ptr->total_tests;
*tests_run_ptr += tv_ptr->tests_run;
*tests_skipped_ptr += tv_ptr->tests_skipped;
return;
} /* ckrbrd_hs_dr_pio_test__run_test() */
/*-------------------------------------------------------------------------
* Function: ckrbrd_hs_dr_pio_test()
*
* Purpose: Test I/O to/from hyperslab selections of different rank in
* the parallel case.
*
* Return: void
*
* Programmer: JRM -- 9/18/09
*
*-------------------------------------------------------------------------
*/
static void
ckrbrd_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
{
int express_test;
int local_express_test;
int mpi_size = -1;
int mpi_rank = -1;
int test_num = 0;
int edge_size;
int checker_edge_size = 3;
int chunk_edge_size = 0;
int small_rank = 3;
int large_rank = 4;
int mpi_result;
hid_t dset_type = H5T_NATIVE_UINT;
int skips = 0;
int max_skips = 0;
/* The following table list the number of sub-tests skipped between
* each test that is actually executed as a function of the express
* test level. Note that any value in excess of 4880 will cause all
* sub tests to be skipped.
*/
int max_skips_tbl[4] = {0, 4, 64, 1024};
int64_t total_tests = 0;
int64_t tests_run = 0;
int64_t tests_skipped = 0;
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
edge_size = (mpi_size > 6 ? mpi_size : 6);
local_express_test = EXPRESS_MODE; /* GetTestExpress(); */
HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned));
mpi_result = MPI_Allreduce((void *)&local_express_test, (void *)&express_test, 1, MPI_INT, MPI_MAX,
MPI_COMM_WORLD);
VRFY((mpi_result == MPI_SUCCESS), "MPI_Allreduce(0) succeeded");
if (local_express_test < 0) {
max_skips = max_skips_tbl[0];
}
else if (local_express_test > 3) {
max_skips = max_skips_tbl[3];
}
else {
max_skips = max_skips_tbl[local_express_test];
}
#if 0
{
int DebugWait = 1;
while (DebugWait) ;
}
#endif
for (large_rank = 3; large_rank <= PAR_SS_DR_MAX_RANK; large_rank++) {
for (small_rank = 2; small_rank < large_rank; small_rank++) {
switch (sstest_type) {
case IND_CONTIG:
/* contiguous data set, independent I/O */
chunk_edge_size = 0;
ckrbrd_hs_dr_pio_test__run_test(test_num, edge_size, checker_edge_size, chunk_edge_size,
small_rank, large_rank, FALSE, dset_type, express_test,
&skips, max_skips, &total_tests, &tests_run,
&tests_skipped, mpi_rank);
test_num++;
break;
/* end of case IND_CONTIG */
case COL_CONTIG:
/* contiguous data set, collective I/O */
chunk_edge_size = 0;
ckrbrd_hs_dr_pio_test__run_test(test_num, edge_size, checker_edge_size, chunk_edge_size,
small_rank, large_rank, TRUE, dset_type, express_test,
&skips, max_skips, &total_tests, &tests_run,
&tests_skipped, mpi_rank);
test_num++;
break;
/* end of case COL_CONTIG */
case IND_CHUNKED:
/* chunked data set, independent I/O */
chunk_edge_size = 5;
ckrbrd_hs_dr_pio_test__run_test(test_num, edge_size, checker_edge_size, chunk_edge_size,
small_rank, large_rank, FALSE, dset_type, express_test,
&skips, max_skips, &total_tests, &tests_run,
&tests_skipped, mpi_rank);
test_num++;
break;
/* end of case IND_CHUNKED */
case COL_CHUNKED:
/* chunked data set, collective I/O */
chunk_edge_size = 5;
ckrbrd_hs_dr_pio_test__run_test(test_num, edge_size, checker_edge_size, chunk_edge_size,
small_rank, large_rank, TRUE, dset_type, express_test,
&skips, max_skips, &total_tests, &tests_run,
&tests_skipped, mpi_rank);
test_num++;
break;
/* end of case COL_CHUNKED */
default:
VRFY((FALSE), "unknown test type");
break;
} /* end of switch(sstest_type) */
#if CONTIG_HS_DR_PIO_TEST__DEBUG
if ((MAINPROCESS) && (tests_skipped > 0)) {
HDfprintf(stdout, " run/skipped/total = %" PRId64 "/%" PRId64 "/%" PRId64 ".\n",
tests_run, tests_skipped, total_tests);
}
#endif /* CONTIG_HS_DR_PIO_TEST__DEBUG */
}
}
if (MAINPROCESS) {
if (tests_skipped > 0) {
HDfprintf(stdout, " %" PRId64 " of %" PRId64 " subtests skipped to expedite testing.\n",
tests_skipped, total_tests);
}
else
HDprintf("\n");
}
return;
} /* ckrbrd_hs_dr_pio_test() */
/* Main Body. Here for now, may have to move them to a separated file later. */
/*
* Main driver of the Parallel HDF5 tests
*/
#include "testphdf5.h"
#ifndef PATH_MAX
#define PATH_MAX 512
#endif /* !PATH_MAX */
/* global variables */
int dim0;
int dim1;
int chunkdim0;
int chunkdim1;
int nerrors = 0; /* errors count */
int ndatasets = 300; /* number of datasets to create*/
int ngroups = 512; /* number of groups to create in root
* group. */
int facc_type = FACC_MPIO; /*Test file access type */
int dxfer_coll_type = DXFER_COLLECTIVE_IO;
H5E_auto2_t old_func; /* previous error handler */
void *old_client_data; /* previous error handler arg.*/
/* other option flags */
#ifdef USE_PAUSE
/* pause the process for a moment to allow debugger to attach if desired. */
/* Will pause more if greenlight file is not persent but will eventually */
/* continue. */
#include <sys/types.h>
#include <sys/stat.h>
void
pause_proc(void)
{
int pid;
h5_stat_t statbuf;
char greenlight[] = "go";
int maxloop = 10;
int loops = 0;
int time_int = 10;
/* mpi variables */
int mpi_size, mpi_rank;
int mpi_namelen;
char mpi_name[MPI_MAX_PROCESSOR_NAME];
pid = getpid();
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Get_processor_name(mpi_name, &mpi_namelen);
if (MAINPROCESS)
while ((HDstat(greenlight, &statbuf) == -1) && loops < maxloop) {
if (!loops++) {
HDprintf("Proc %d (%*s, %d): to debug, attach %d\n", mpi_rank, mpi_namelen, mpi_name, pid,
pid);
}
HDprintf("waiting(%ds) for file %s ...\n", time_int, greenlight);
fflush(stdout);
HDsleep(time_int);
}
MPI_Barrier(MPI_COMM_WORLD);
}
/* Use the Profile feature of MPI to call the pause_proc() */
int
MPI_Init(int *argc, char ***argv)
{
int ret_code;
ret_code = PMPI_Init(argc, argv);
pause_proc();
return (ret_code);
}
#endif /* USE_PAUSE */
/*
* Show command usage
*/
static void
usage(void)
{
HDprintf(" [-r] [-w] [-m<n_datasets>] [-n<n_groups>] "
"[-o] [-f <prefix>] [-d <dim0> <dim1>]\n");
HDprintf("\t-m<n_datasets>"
"\tset number of datasets for the multiple dataset test\n");
HDprintf("\t-n<n_groups>"
"\tset number of groups for the multiple group test\n");
#if 0
HDprintf("\t-f <prefix>\tfilename prefix\n");
#endif
HDprintf("\t-2\t\tuse Split-file together with MPIO\n");
HDprintf("\t-d <factor0> <factor1>\tdataset dimensions factors. Defaults (%d,%d)\n", ROW_FACTOR,
COL_FACTOR);
HDprintf("\t-c <dim0> <dim1>\tdataset chunk dimensions. Defaults (dim0/10,dim1/10)\n");
HDprintf("\n");
}
/*
* parse the command line options
*/
static int
parse_options(int argc, char **argv)
{
int mpi_size, mpi_rank; /* mpi variables */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* setup default chunk-size. Make sure sizes are > 0 */
chunkdim0 = (dim0 + 9) / 10;
chunkdim1 = (dim1 + 9) / 10;
while (--argc) {
if (**(++argv) != '-') {
break;
}
else {
switch (*(*argv + 1)) {
case 'm':
ndatasets = atoi((*argv + 1) + 1);
if (ndatasets < 0) {
nerrors++;
return (1);
}
break;
case 'n':
ngroups = atoi((*argv + 1) + 1);
if (ngroups < 0) {
nerrors++;
return (1);
}
break;
#if 0
case 'f': if (--argc < 1) {
nerrors++;
return(1);
}
if (**(++argv) == '-') {
nerrors++;
return(1);
}
paraprefix = *argv;
break;
#endif
case 'i': /* Collective MPI-IO access with independent IO */
dxfer_coll_type = DXFER_INDEPENDENT_IO;
break;
case '2': /* Use the split-file driver with MPIO access */
/* Can use $HDF5_METAPREFIX to define the */
/* meta-file-prefix. */
facc_type = FACC_MPIO | FACC_SPLIT;
break;
case 'd': /* dimensizes */
if (--argc < 2) {
nerrors++;
return (1);
}
dim0 = atoi(*(++argv)) * mpi_size;
argc--;
dim1 = atoi(*(++argv)) * mpi_size;
/* set default chunkdim sizes too */
chunkdim0 = (dim0 + 9) / 10;
chunkdim1 = (dim1 + 9) / 10;
break;
case 'c': /* chunk dimensions */
if (--argc < 2) {
nerrors++;
return (1);
}
chunkdim0 = atoi(*(++argv));
argc--;
chunkdim1 = atoi(*(++argv));
break;
case 'h': /* print help message--return with nerrors set */
return (1);
default:
HDprintf("Illegal option(%s)\n", *argv);
nerrors++;
return (1);
}
}
} /*while*/
/* check validity of dimension and chunk sizes */
if (dim0 <= 0 || dim1 <= 0) {
HDprintf("Illegal dim sizes (%d, %d)\n", dim0, dim1);
nerrors++;
return (1);
}
if (chunkdim0 <= 0 || chunkdim1 <= 0) {
HDprintf("Illegal chunkdim sizes (%d, %d)\n", chunkdim0, chunkdim1);
nerrors++;
return (1);
}
/* Make sure datasets can be divided into equal portions by the processes */
if ((dim0 % mpi_size) || (dim1 % mpi_size)) {
if (MAINPROCESS)
HDprintf("dim0(%d) and dim1(%d) must be multiples of processes(%d)\n", dim0, dim1, mpi_size);
nerrors++;
return (1);
}
/* compose the test filenames */
{
int i, n;
n = sizeof(FILENAME) / sizeof(FILENAME[0]) - 1; /* exclude the NULL */
for (i = 0; i < n; i++)
strncpy(filenames[i], FILENAME[i], PATH_MAX);
#if 0 /* no support for VFDs right now */
if (h5_fixname(FILENAME[i], fapl, filenames[i], PATH_MAX) == NULL) {
HDprintf("h5_fixname failed\n");
nerrors++;
return (1);
}
#endif
if (MAINPROCESS) {
HDprintf("Test filenames are:\n");
for (i = 0; i < n; i++)
HDprintf(" %s\n", filenames[i]);
}
}
return (0);
}
/*
* Create the appropriate File access property list
*/
hid_t
create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type)
{
hid_t ret_pl = -1;
herr_t ret; /* generic return value */
int mpi_rank; /* mpi variables */
/* need the rank for error checking macros */
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((ret_pl >= 0), "H5P_FILE_ACCESS");
if (l_facc_type == FACC_DEFAULT)
return (ret_pl);
if (l_facc_type == FACC_MPIO) {
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(ret_pl, comm, info);
VRFY((ret >= 0), "");
ret = H5Pset_all_coll_metadata_ops(ret_pl, TRUE);
VRFY((ret >= 0), "");
ret = H5Pset_coll_metadata_write(ret_pl, TRUE);
VRFY((ret >= 0), "");
return (ret_pl);
}
if (l_facc_type == (FACC_MPIO | FACC_SPLIT)) {
hid_t mpio_pl;
mpio_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((mpio_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(mpio_pl, comm, info);
VRFY((ret >= 0), "");
/* setup file access template */
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((ret_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_split(ret_pl, ".meta", mpio_pl, ".raw", mpio_pl);
VRFY((ret >= 0), "H5Pset_fapl_split succeeded");
H5Pclose(mpio_pl);
return (ret_pl);
}
/* unknown file access types */
return (ret_pl);
}
/* Shape Same test using contiguous hyperslab using independent IO on contiguous datasets */
static void
sscontig1(void)
{
contig_hs_dr_pio_test(IND_CONTIG);
}
/* Shape Same test using contiguous hyperslab using collective IO on contiguous datasets */
static void
sscontig2(void)
{
contig_hs_dr_pio_test(COL_CONTIG);
}
/* Shape Same test using contiguous hyperslab using independent IO on chunked datasets */
static void
sscontig3(void)
{
contig_hs_dr_pio_test(IND_CHUNKED);
}
/* Shape Same test using contiguous hyperslab using collective IO on chunked datasets */
static void
sscontig4(void)
{
contig_hs_dr_pio_test(COL_CHUNKED);
}
/* Shape Same test using checker hyperslab using independent IO on contiguous datasets */
static void
sschecker1(void)
{
ckrbrd_hs_dr_pio_test(IND_CONTIG);
}
/* Shape Same test using checker hyperslab using collective IO on contiguous datasets */
static void
sschecker2(void)
{
ckrbrd_hs_dr_pio_test(COL_CONTIG);
}
/* Shape Same test using checker hyperslab using independent IO on chunked datasets */
static void
sschecker3(void)
{
ckrbrd_hs_dr_pio_test(IND_CHUNKED);
}
/* Shape Same test using checker hyperslab using collective IO on chunked datasets */
static void
sschecker4(void)
{
ckrbrd_hs_dr_pio_test(COL_CHUNKED);
}
int
main(int argc, char **argv)
{
int mpi_size, mpi_rank; /* mpi variables */
#ifndef H5_HAVE_WIN32_API
/* Un-buffer the stdout and stderr */
HDsetbuf(stderr, NULL);
HDsetbuf(stdout, NULL);
#endif
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
dim0 = ROW_FACTOR * mpi_size;
dim1 = COL_FACTOR * mpi_size;
if (MAINPROCESS) {
HDprintf("===================================\n");
HDprintf("Shape Same Tests Start\n");
HDprintf(" express_test = %d.\n", EXPRESS_MODE /* GetTestExpress() */);
HDprintf("===================================\n");
}
/* Attempt to turn off atexit post processing so that in case errors
* happen during the test and the process is aborted, it will not get
* hang in the atexit post processing in which it may try to make MPI
* calls. By then, MPI calls may not work.
*/
if (H5dont_atexit() < 0) {
if (MAINPROCESS)
HDprintf("%d: Failed to turn off atexit processing. Continue.\n", mpi_rank);
};
H5open();
/* h5_show_hostname(); */
fapl = H5Pcreate(H5P_FILE_ACCESS);
/* Get the capability flag of the VOL connector being used */
if (H5Pget_vol_cap_flags(fapl, &vol_cap_flags_g) < 0) {
if (MAINPROCESS)
HDprintf("Failed to get the capability flag of the VOL connector being used\n");
MPI_Finalize();
return 0;
}
/* Make sure the connector supports the API functions being tested. This test only
* uses a few API functions, such as H5Fcreate/close/delete, H5Dcreate/write/read/close,
*/
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS)
HDprintf("API functions for basic file and dataset aren't supported with this connector\n");
MPI_Finalize();
return 0;
}
#if 0
HDmemset(filenames, 0, sizeof(filenames));
for (int i = 0; i < NFILENAME; i++) {
if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) {
HDprintf("couldn't allocate filename array\n");
MPI_Abort(MPI_COMM_WORLD, -1);
}
}
#endif
/* Initialize testing framework */
/* TestInit(argv[0], usage, parse_options); */
if (parse_options(argc, argv)) {
usage();
return 1;
}
if (dxfer_coll_type == DXFER_INDEPENDENT_IO && MAINPROCESS) {
HDprintf("===================================\n"
" Using Independent I/O with file set view to replace collective I/O \n"
"===================================\n");
}
/* Shape Same tests using contiguous hyperslab */
#if 0
AddTest("sscontig1", sscontig1, NULL,
"Cntg hslab, ind IO, cntg dsets", filenames[0]);
AddTest("sscontig2", sscontig2, NULL,
"Cntg hslab, col IO, cntg dsets", filenames[0]);
AddTest("sscontig3", sscontig3, NULL,
"Cntg hslab, ind IO, chnk dsets", filenames[0]);
AddTest("sscontig4", sscontig4, NULL,
"Cntg hslab, col IO, chnk dsets", filenames[0]);
#endif
if (MAINPROCESS) {
printf("Cntg hslab, ind IO, cntg dsets\n");
fflush(stdout);
}
sscontig1();
if (MAINPROCESS) {
printf("Cntg hslab, col IO, cntg dsets\n");
fflush(stdout);
}
sscontig2();
if (MAINPROCESS) {
printf("Cntg hslab, ind IO, chnk dsets\n");
fflush(stdout);
}
sscontig3();
if (MAINPROCESS) {
printf("Cntg hslab, col IO, chnk dsets\n");
fflush(stdout);
}
sscontig4();
/* Shape Same tests using checker board hyperslab */
#if 0
AddTest("sschecker1", sschecker1, NULL,
"Check hslab, ind IO, cntg dsets", filenames[0]);
AddTest("sschecker2", sschecker2, NULL,
"Check hslab, col IO, cntg dsets", filenames[0]);
AddTest("sschecker3", sschecker3, NULL,
"Check hslab, ind IO, chnk dsets", filenames[0]);
AddTest("sschecker4", sschecker4, NULL,
"Check hslab, col IO, chnk dsets", filenames[0]);
#endif
if (MAINPROCESS) {
printf("Check hslab, ind IO, cntg dsets\n");
fflush(stdout);
}
sschecker1();
if (MAINPROCESS) {
printf("Check hslab, col IO, cntg dsets\n");
fflush(stdout);
}
sschecker2();
if (MAINPROCESS) {
printf("Check hslab, ind IO, chnk dsets\n");
fflush(stdout);
}
sschecker3();
if (MAINPROCESS) {
printf("Check hslab, col IO, chnk dsets\n");
fflush(stdout);
}
sschecker4();
/* Display testing information */
/* TestInfo(argv[0]); */
/* setup file access property list */
H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL);
/* Parse command line arguments */
/* TestParseCmdLine(argc, argv); */
/* Perform requested testing */
/* PerformTests(); */
/* make sure all processes are finished before final report, cleanup
* and exit.
*/
MPI_Barrier(MPI_COMM_WORLD);
/* Display test summary, if requested */
/* if (MAINPROCESS && GetTestSummary())
TestSummary(); */
/* Clean up test files */
/* h5_clean_files(FILENAME, fapl); */
H5Fdelete(FILENAME[0], fapl);
H5Pclose(fapl);
/* nerrors += GetTestNumErrs(); */
/* Gather errors from all processes */
{
int temp;
MPI_Allreduce(&nerrors, &temp, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
nerrors = temp;
}
if (MAINPROCESS) { /* only process 0 reports */
HDprintf("===================================\n");
if (nerrors)
HDprintf("***Shape Same tests detected %d errors***\n", nerrors);
else
HDprintf("Shape Same tests finished successfully\n");
HDprintf("===================================\n");
}
#if 0
for (int i = 0; i < NFILENAME; i++) {
HDfree(filenames[i]);
filenames[i] = NULL;
}
#endif
/* close HDF5 library */
H5close();
/* Release test infrastructure */
/* TestShutdown(); */
MPI_Finalize();
/* cannot just return (nerrors) because exit code is limited to 1byte */
return (nerrors != 0);
}
+2622
View File
@@ -0,0 +1,2622 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
This program will test irregular hyperslab selections with collective write and read.
The way to test whether collective write and read works is to use independent IO
output to verify the collective output.
1) We will write two datasets with the same hyperslab selection settings;
one in independent mode,
one in collective mode,
2) We will read two datasets with the same hyperslab selection settings,
1. independent read to read independent output,
independent read to read collecive output,
Compare the result,
If the result is the same, then collective write succeeds.
2. collective read to read independent output,
independent read to read independent output,
Compare the result,
If the result is the same, then collective read succeeds.
*/
#include "hdf5.h"
#if 0
#include "H5private.h"
#endif
#include "testphdf5.h"
#define LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG 0
static void coll_write_test(int chunk_factor);
static void coll_read_test(void);
/*-------------------------------------------------------------------------
* Function: coll_irregular_cont_write
*
* Purpose: Wrapper to test the collectively irregular hyperslab write in
* contiguous storage
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_cont_write(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_write_test(0);
}
/*-------------------------------------------------------------------------
* Function: coll_irregular_cont_read
*
* Purpose: Wrapper to test the collectively irregular hyperslab read in
* contiguous storage
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_cont_read(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_read_test();
}
/*-------------------------------------------------------------------------
* Function: coll_irregular_simple_chunk_write
*
* Purpose: Wrapper to test the collectively irregular hyperslab write in
* chunk storage(1 chunk)
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_simple_chunk_write(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_write_test(1);
}
/*-------------------------------------------------------------------------
* Function: coll_irregular_simple_chunk_read
*
* Purpose: Wrapper to test the collectively irregular hyperslab read in chunk
* storage(1 chunk)
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_simple_chunk_read(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_read_test();
}
/*-------------------------------------------------------------------------
* Function: coll_irregular_complex_chunk_write
*
* Purpose: Wrapper to test the collectively irregular hyperslab write in chunk
* storage(4 chunks)
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_complex_chunk_write(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_write_test(4);
}
/*-------------------------------------------------------------------------
* Function: coll_irregular_complex_chunk_read
*
* Purpose: Wrapper to test the collectively irregular hyperslab read in chunk
* storage(1 chunk)
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_irregular_complex_chunk_read(void)
{
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file dataset, or dataset more aren't supported with this "
"connector\n");
fflush(stdout);
}
return;
}
coll_read_test();
}
/*-------------------------------------------------------------------------
* Function: coll_write_test
*
* Purpose: To test the collectively irregular hyperslab write in chunk
* storage
* Input: number of chunks on each dimension
* if number is equal to 0, contiguous storage
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
void
coll_write_test(int chunk_factor)
{
const char *filename;
hid_t facc_plist, dxfer_plist, dcrt_plist;
hid_t file, datasetc, dataseti; /* File and dataset identifiers */
hid_t mspaceid1, mspaceid, fspaceid, fspaceid1; /* Dataspace identifiers */
hsize_t mdim1[1]; /* Dimension size of the first dataset (in memory) */
hsize_t fsdim[2]; /* Dimension sizes of the dataset (on disk) */
hsize_t mdim[2]; /* Dimension sizes of the dataset in memory when we
* read selection from the dataset on the disk
*/
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 */
hsize_t chunk_dims[2];
herr_t ret;
int i;
int fillvalue = 0; /* Fill value for the dataset */
int *matrix_out = NULL;
int *matrix_out1 = NULL; /* Buffer to read from the dataset */
int *vector = NULL;
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
/*set up MPI parameters */
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
/* Obtain file name */
filename = PARATESTFILE /* GetTestParameters() */;
/*
* Buffers' initialization.
*/
mdim1[0] = (hsize_t)(MSPACE1_DIM * mpi_size);
mdim[0] = MSPACE_DIM1;
mdim[1] = (hsize_t)(MSPACE_DIM2 * mpi_size);
fsdim[0] = FSPACE_DIM1;
fsdim[1] = (hsize_t)(FSPACE_DIM2 * mpi_size);
vector = (int *)HDmalloc(sizeof(int) * (size_t)mdim1[0] * (size_t)mpi_size);
matrix_out = (int *)HDmalloc(sizeof(int) * (size_t)mdim[0] * (size_t)mdim[1] * (size_t)mpi_size);
matrix_out1 = (int *)HDmalloc(sizeof(int) * (size_t)mdim[0] * (size_t)mdim[1] * (size_t)mpi_size);
HDmemset(vector, 0, sizeof(int) * (size_t)mdim1[0] * (size_t)mpi_size);
vector[0] = vector[MSPACE1_DIM * mpi_size - 1] = -1;
for (i = 1; i < MSPACE1_DIM * mpi_size - 1; i++)
vector[i] = (int)i;
/* Grab file access property list */
facc_plist = create_faccess_plist(comm, info, facc_type);
VRFY((facc_plist >= 0), "");
/*
* Create a file.
*/
file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, facc_plist);
VRFY((file >= 0), "H5Fcreate succeeded");
/*
* Create property list for a dataset and set up fill values.
*/
dcrt_plist = H5Pcreate(H5P_DATASET_CREATE);
VRFY((dcrt_plist >= 0), "");
ret = H5Pset_fill_value(dcrt_plist, H5T_NATIVE_INT, &fillvalue);
VRFY((ret >= 0), "Fill value creation property list succeeded");
if (chunk_factor != 0) {
chunk_dims[0] = fsdim[0] / (hsize_t)chunk_factor;
chunk_dims[1] = fsdim[1] / (hsize_t)chunk_factor;
ret = H5Pset_chunk(dcrt_plist, 2, chunk_dims);
VRFY((ret >= 0), "chunk creation property list succeeded");
}
/*
*
* Create dataspace for the first dataset in the disk.
* dim1 = 9
* dim2 = 3600
*
*
*/
fspaceid = H5Screate_simple(FSPACE_RANK, fsdim, NULL);
VRFY((fspaceid >= 0), "file dataspace created succeeded");
/*
* Create dataset in the file. Notice that creation
* property list dcrt_plist is used.
*/
datasetc =
H5Dcreate2(file, "collect_write", H5T_NATIVE_INT, fspaceid, H5P_DEFAULT, dcrt_plist, H5P_DEFAULT);
VRFY((datasetc >= 0), "dataset created succeeded");
dataseti =
H5Dcreate2(file, "independ_write", H5T_NATIVE_INT, fspaceid, H5P_DEFAULT, dcrt_plist, H5P_DEFAULT);
VRFY((dataseti >= 0), "dataset created succeeded");
/* The First selection for FILE
*
* block (3,2)
* stride(4,3)
* count (1,768/mpi_size)
* start (0,1+768*3*mpi_rank/mpi_size)
*
*/
start[0] = FHSTART0;
start[1] = (hsize_t)(FHSTART1 + mpi_rank * FHSTRIDE1 * FHCOUNT1);
stride[0] = FHSTRIDE0;
stride[1] = FHSTRIDE1;
count[0] = FHCOUNT0;
count[1] = FHCOUNT1;
block[0] = FHBLOCK0;
block[1] = FHBLOCK1;
ret = H5Sselect_hyperslab(fspaceid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* The Second selection for FILE
*
* block (3,768)
* stride (1,1)
* count (1,1)
* start (4,768*mpi_rank/mpi_size)
*
*/
start[0] = SHSTART0;
start[1] = (hsize_t)(SHSTART1 + SHCOUNT1 * SHBLOCK1 * mpi_rank);
stride[0] = SHSTRIDE0;
stride[1] = SHSTRIDE1;
count[0] = SHCOUNT0;
count[1] = SHCOUNT1;
block[0] = SHBLOCK0;
block[1] = SHBLOCK1;
ret = H5Sselect_hyperslab(fspaceid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Create dataspace for the first dataset in the memory
* dim1 = 27000
*
*/
mspaceid1 = H5Screate_simple(MSPACE1_RANK, mdim1, NULL);
VRFY((mspaceid1 >= 0), "memory dataspace created succeeded");
/*
* Memory space is 1-D, this is a good test to check
* whether a span-tree derived datatype needs to be built.
* block 1
* stride 1
* count 6912/mpi_size
* start 1
*
*/
start[0] = MHSTART0;
stride[0] = MHSTRIDE0;
count[0] = MHCOUNT0;
block[0] = MHBLOCK0;
ret = H5Sselect_hyperslab(mspaceid1, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* independent write */
ret = H5Dwrite(dataseti, H5T_NATIVE_INT, mspaceid1, fspaceid, H5P_DEFAULT, vector);
VRFY((ret >= 0), "dataset independent write succeed");
dxfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(dxfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "MPIO data transfer property list succeed");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* collective write */
ret = H5Dwrite(datasetc, H5T_NATIVE_INT, mspaceid1, fspaceid, dxfer_plist, vector);
VRFY((ret >= 0), "dataset collective write succeed");
ret = H5Sclose(mspaceid1);
VRFY((ret >= 0), "");
ret = H5Sclose(fspaceid);
VRFY((ret >= 0), "");
/*
* Close dataset.
*/
ret = H5Dclose(datasetc);
VRFY((ret >= 0), "");
ret = H5Dclose(dataseti);
VRFY((ret >= 0), "");
/*
* Close the file.
*/
ret = H5Fclose(file);
VRFY((ret >= 0), "");
/*
* Close property list
*/
ret = H5Pclose(facc_plist);
VRFY((ret >= 0), "");
ret = H5Pclose(dxfer_plist);
VRFY((ret >= 0), "");
ret = H5Pclose(dcrt_plist);
VRFY((ret >= 0), "");
/*
* Open the file.
*/
/***
For testing collective hyperslab selection write
In this test, we are using independent read to check
the correctedness of collective write compared with
independent write,
In order to thoroughly test this feature, we choose
a different selection set for reading the data out.
***/
/* Obtain file access property list with MPI-IO driver */
facc_plist = create_faccess_plist(comm, info, facc_type);
VRFY((facc_plist >= 0), "");
file = H5Fopen(filename, H5F_ACC_RDONLY, facc_plist);
VRFY((file >= 0), "H5Fopen succeeded");
/*
* Open the dataset.
*/
datasetc = H5Dopen2(file, "collect_write", H5P_DEFAULT);
VRFY((datasetc >= 0), "H5Dopen2 succeeded");
dataseti = H5Dopen2(file, "independ_write", H5P_DEFAULT);
VRFY((dataseti >= 0), "H5Dopen2 succeeded");
/*
* Get dataspace of the open dataset.
*/
fspaceid = H5Dget_space(datasetc);
VRFY((fspaceid >= 0), "file dataspace obtained succeeded");
fspaceid1 = H5Dget_space(dataseti);
VRFY((fspaceid1 >= 0), "file dataspace obtained succeeded");
/* The First selection for FILE to read
*
* block (1,1)
* stride(1.1)
* count (3,768/mpi_size)
* start (1,2+768*mpi_rank/mpi_size)
*
*/
start[0] = RFFHSTART0;
start[1] = (hsize_t)(RFFHSTART1 + mpi_rank * RFFHCOUNT1);
block[0] = RFFHBLOCK0;
block[1] = RFFHBLOCK1;
stride[0] = RFFHSTRIDE0;
stride[1] = RFFHSTRIDE1;
count[0] = RFFHCOUNT0;
count[1] = RFFHCOUNT1;
/* The first selection of the dataset generated by collective write */
ret = H5Sselect_hyperslab(fspaceid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* The first selection of the dataset generated by independent write */
ret = H5Sselect_hyperslab(fspaceid1, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* The Second selection for FILE to read
*
* block (1,1)
* stride(1.1)
* count (3,1536/mpi_size)
* start (2,4+1536*mpi_rank/mpi_size)
*
*/
start[0] = RFSHSTART0;
start[1] = (hsize_t)(RFSHSTART1 + RFSHCOUNT1 * mpi_rank);
block[0] = RFSHBLOCK0;
block[1] = RFSHBLOCK1;
stride[0] = RFSHSTRIDE0;
stride[1] = RFSHSTRIDE0;
count[0] = RFSHCOUNT0;
count[1] = RFSHCOUNT1;
/* The second selection of the dataset generated by collective write */
ret = H5Sselect_hyperslab(fspaceid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* The second selection of the dataset generated by independent write */
ret = H5Sselect_hyperslab(fspaceid1, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Create memory dataspace.
* rank = 2
* mdim1 = 9
* mdim2 = 3600
*
*/
mspaceid = H5Screate_simple(MSPACE_RANK, mdim, NULL);
/*
* Select two hyperslabs in memory. Hyperslabs has the same
* size and shape as the selected hyperslabs for the file dataspace
* Only the starting point is different.
* The first selection
* block (1,1)
* stride(1.1)
* count (3,768/mpi_size)
* start (0,768*mpi_rank/mpi_size)
*
*/
start[0] = RMFHSTART0;
start[1] = (hsize_t)(RMFHSTART1 + mpi_rank * RMFHCOUNT1);
block[0] = RMFHBLOCK0;
block[1] = RMFHBLOCK1;
stride[0] = RMFHSTRIDE0;
stride[1] = RMFHSTRIDE1;
count[0] = RMFHCOUNT0;
count[1] = RMFHCOUNT1;
ret = H5Sselect_hyperslab(mspaceid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Select two hyperslabs in memory. Hyperslabs has the same
* size and shape as the selected hyperslabs for the file dataspace
* Only the starting point is different.
* The second selection
* block (1,1)
* stride(1,1)
* count (3,1536/mpi_size)
* start (1,2+1536*mpi_rank/mpi_size)
*
*/
start[0] = RMSHSTART0;
start[1] = (hsize_t)(RMSHSTART1 + mpi_rank * RMSHCOUNT1);
block[0] = RMSHBLOCK0;
block[1] = RMSHBLOCK1;
stride[0] = RMSHSTRIDE0;
stride[1] = RMSHSTRIDE1;
count[0] = RMSHCOUNT0;
count[1] = RMSHCOUNT1;
ret = H5Sselect_hyperslab(mspaceid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Initialize data buffer.
*/
HDmemset(matrix_out, 0, sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
HDmemset(matrix_out1, 0, sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
/*
* Read data back to the buffer matrix_out.
*/
ret = H5Dread(datasetc, H5T_NATIVE_INT, mspaceid, fspaceid, H5P_DEFAULT, matrix_out);
VRFY((ret >= 0), "H5D independent read succeed");
ret = H5Dread(dataseti, H5T_NATIVE_INT, mspaceid, fspaceid, H5P_DEFAULT, matrix_out1);
VRFY((ret >= 0), "H5D independent read succeed");
ret = 0;
for (i = 0; i < MSPACE_DIM1 * MSPACE_DIM2 * mpi_size; i++) {
if (matrix_out[i] != matrix_out1[i])
ret = -1;
if (ret < 0)
break;
}
VRFY((ret >= 0), "H5D irregular collective write succeed");
/*
* Close memory file and memory dataspaces.
*/
ret = H5Sclose(mspaceid);
VRFY((ret >= 0), "");
ret = H5Sclose(fspaceid);
VRFY((ret >= 0), "");
/*
* Close dataset.
*/
ret = H5Dclose(dataseti);
VRFY((ret >= 0), "");
ret = H5Dclose(datasetc);
VRFY((ret >= 0), "");
/*
* Close property list
*/
ret = H5Pclose(facc_plist);
VRFY((ret >= 0), "");
/*
* Close the file.
*/
ret = H5Fclose(file);
VRFY((ret >= 0), "");
if (vector)
HDfree(vector);
if (matrix_out)
HDfree(matrix_out);
if (matrix_out1)
HDfree(matrix_out1);
return;
}
/*-------------------------------------------------------------------------
* Function: coll_read_test
*
* Purpose: To test the collectively irregular hyperslab read in chunk
* storage
* Input: number of chunks on each dimension
* if number is equal to 0, contiguous storage
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Unknown
* Dec 2nd, 2004
*
*-------------------------------------------------------------------------
*/
static void
coll_read_test(void)
{
const char *filename;
hid_t facc_plist, dxfer_plist;
hid_t file, dataseti; /* File and dataset identifiers */
hid_t mspaceid, fspaceid1; /* Dataspace identifiers */
/* Dimension sizes of the dataset (on disk) */
hsize_t mdim[2]; /* Dimension sizes of the dataset in memory when we
* read selection from the dataset on the disk
*/
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 */
herr_t ret;
int i;
int *matrix_out;
int *matrix_out1; /* Buffer to read from the dataset */
int mpi_size, mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
/*set up MPI parameters */
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
/* Obtain file name */
filename = PARATESTFILE /* GetTestParameters() */;
/* Initialize the buffer */
mdim[0] = MSPACE_DIM1;
mdim[1] = (hsize_t)(MSPACE_DIM2 * mpi_size);
matrix_out = (int *)HDmalloc(sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
matrix_out1 = (int *)HDmalloc(sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
/*** For testing collective hyperslab selection read ***/
/* Obtain file access property list */
facc_plist = create_faccess_plist(comm, info, facc_type);
VRFY((facc_plist >= 0), "");
/*
* Open the file.
*/
file = H5Fopen(filename, H5F_ACC_RDONLY, facc_plist);
VRFY((file >= 0), "H5Fopen succeeded");
/*
* Open the dataset.
*/
dataseti = H5Dopen2(file, "independ_write", H5P_DEFAULT);
VRFY((dataseti >= 0), "H5Dopen2 succeeded");
/*
* Get dataspace of the open dataset.
*/
fspaceid1 = H5Dget_space(dataseti);
VRFY((fspaceid1 >= 0), "file dataspace obtained succeeded");
/* The First selection for FILE to read
*
* block (1,1)
* stride(1.1)
* count (3,768/mpi_size)
* start (1,2+768*mpi_rank/mpi_size)
*
*/
start[0] = RFFHSTART0;
start[1] = (hsize_t)(RFFHSTART1 + mpi_rank * RFFHCOUNT1);
block[0] = RFFHBLOCK0;
block[1] = RFFHBLOCK1;
stride[0] = RFFHSTRIDE0;
stride[1] = RFFHSTRIDE1;
count[0] = RFFHCOUNT0;
count[1] = RFFHCOUNT1;
ret = H5Sselect_hyperslab(fspaceid1, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/* The Second selection for FILE to read
*
* block (1,1)
* stride(1.1)
* count (3,1536/mpi_size)
* start (2,4+1536*mpi_rank/mpi_size)
*
*/
start[0] = RFSHSTART0;
start[1] = (hsize_t)(RFSHSTART1 + RFSHCOUNT1 * mpi_rank);
block[0] = RFSHBLOCK0;
block[1] = RFSHBLOCK1;
stride[0] = RFSHSTRIDE0;
stride[1] = RFSHSTRIDE0;
count[0] = RFSHCOUNT0;
count[1] = RFSHCOUNT1;
ret = H5Sselect_hyperslab(fspaceid1, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Create memory dataspace.
*/
mspaceid = H5Screate_simple(MSPACE_RANK, mdim, NULL);
/*
* Select two hyperslabs in memory. Hyperslabs has the same
* size and shape as the selected hyperslabs for the file dataspace.
* Only the starting point is different.
* The first selection
* block (1,1)
* stride(1.1)
* count (3,768/mpi_size)
* start (0,768*mpi_rank/mpi_size)
*
*/
start[0] = RMFHSTART0;
start[1] = (hsize_t)(RMFHSTART1 + mpi_rank * RMFHCOUNT1);
block[0] = RMFHBLOCK0;
block[1] = RMFHBLOCK1;
stride[0] = RMFHSTRIDE0;
stride[1] = RMFHSTRIDE1;
count[0] = RMFHCOUNT0;
count[1] = RMFHCOUNT1;
ret = H5Sselect_hyperslab(mspaceid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Select two hyperslabs in memory. Hyperslabs has the same
* size and shape as the selected hyperslabs for the file dataspace
* Only the starting point is different.
* The second selection
* block (1,1)
* stride(1,1)
* count (3,1536/mpi_size)
* start (1,2+1536*mpi_rank/mpi_size)
*
*/
start[0] = RMSHSTART0;
start[1] = (hsize_t)(RMSHSTART1 + mpi_rank * RMSHCOUNT1);
block[0] = RMSHBLOCK0;
block[1] = RMSHBLOCK1;
stride[0] = RMSHSTRIDE0;
stride[1] = RMSHSTRIDE1;
count[0] = RMSHCOUNT0;
count[1] = RMSHCOUNT1;
ret = H5Sselect_hyperslab(mspaceid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "hyperslab selection succeeded");
/*
* Initialize data buffer.
*/
HDmemset(matrix_out, 0, sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
HDmemset(matrix_out1, 0, sizeof(int) * (size_t)MSPACE_DIM1 * (size_t)MSPACE_DIM2 * (size_t)mpi_size);
/*
* Read data back to the buffer matrix_out.
*/
dxfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((dxfer_plist >= 0), "");
ret = H5Pset_dxpl_mpio(dxfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "MPIO data transfer property list succeed");
if (dxfer_coll_type == DXFER_INDEPENDENT_IO) {
ret = H5Pset_dxpl_mpio_collective_opt(dxfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "set independent IO collectively succeeded");
}
/* Collective read */
ret = H5Dread(dataseti, H5T_NATIVE_INT, mspaceid, fspaceid1, dxfer_plist, matrix_out);
VRFY((ret >= 0), "H5D collecive read succeed");
ret = H5Pclose(dxfer_plist);
VRFY((ret >= 0), "");
/* Independent read */
ret = H5Dread(dataseti, H5T_NATIVE_INT, mspaceid, fspaceid1, H5P_DEFAULT, matrix_out1);
VRFY((ret >= 0), "H5D independent read succeed");
ret = 0;
for (i = 0; i < MSPACE_DIM1 * MSPACE_DIM2 * mpi_size; i++) {
if (matrix_out[i] != matrix_out1[i])
ret = -1;
if (ret < 0)
break;
}
VRFY((ret >= 0), "H5D contiguous irregular collective read succeed");
/*
* Free read buffers.
*/
HDfree(matrix_out);
HDfree(matrix_out1);
/*
* Close memory file and memory dataspaces.
*/
ret = H5Sclose(mspaceid);
VRFY((ret >= 0), "");
ret = H5Sclose(fspaceid1);
VRFY((ret >= 0), "");
/*
* Close dataset.
*/
ret = H5Dclose(dataseti);
VRFY((ret >= 0), "");
/*
* Close property list
*/
ret = H5Pclose(facc_plist);
VRFY((ret >= 0), "");
/*
* Close the file.
*/
ret = H5Fclose(file);
VRFY((ret >= 0), "");
return;
}
/****************************************************************
**
** lower_dim_size_comp_test__select_checker_board():
**
** Given a dataspace of tgt_rank, and dimensions:
**
** (mpi_size + 1), edge_size, ... , edge_size
**
** edge_size, and a checker_edge_size, select a checker
** board selection of a sel_rank (sel_rank < tgt_rank)
** dimensional slice through the dataspace parallel to the
** sel_rank fastest changing indices, with origin (in the
** higher indices) as indicated by the start array.
**
** Note that this function, is hard coded to presume a
** maximum dataspace rank of 5.
**
** While this maximum is declared as a constant, increasing
** it will require extensive coding in addition to changing
** the value of the constant.
**
** JRM -- 11/11/09
**
****************************************************************/
#define LDSCT_DS_RANK 5
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
#define LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK 0
#endif
#define LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG 0
static void
lower_dim_size_comp_test__select_checker_board(const int mpi_rank, const hid_t tgt_sid, const int tgt_rank,
const hsize_t dims[LDSCT_DS_RANK], const int checker_edge_size,
const int sel_rank, hsize_t sel_start[])
{
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
const char *fcnName = "lower_dim_size_comp_test__select_checker_board():";
#endif
hbool_t first_selection = TRUE;
int i, j, k, l, m;
int ds_offset;
int sel_offset;
const int test_max_rank = LDSCT_DS_RANK; /* must update code if */
/* this changes */
hsize_t base_count;
hsize_t offset_count;
hsize_t start[LDSCT_DS_RANK];
hsize_t stride[LDSCT_DS_RANK];
hsize_t count[LDSCT_DS_RANK];
hsize_t block[LDSCT_DS_RANK];
herr_t ret; /* Generic return value */
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: dims/checker_edge_size = %d %d %d %d %d / %d\n", fcnName, mpi_rank,
(int)dims[0], (int)dims[1], (int)dims[2], (int)dims[3], (int)dims[4], checker_edge_size);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG */
HDassert(0 < checker_edge_size);
HDassert(0 < sel_rank);
HDassert(sel_rank <= tgt_rank);
HDassert(tgt_rank <= test_max_rank);
HDassert(test_max_rank <= LDSCT_DS_RANK);
sel_offset = test_max_rank - sel_rank;
HDassert(sel_offset >= 0);
ds_offset = test_max_rank - tgt_rank;
HDassert(ds_offset >= 0);
HDassert(ds_offset <= sel_offset);
HDassert((hsize_t)checker_edge_size <= dims[sel_offset]);
HDassert(dims[sel_offset] == 10);
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: sel_rank/sel_offset = %d/%d.\n", fcnName, mpi_rank, sel_rank, sel_offset);
HDfprintf(stdout, "%s:%d: tgt_rank/ds_offset = %d/%d.\n", fcnName, mpi_rank, tgt_rank, ds_offset);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG */
/* First, compute the base count (which assumes start == 0
* for the associated offset) and offset_count (which
* assumes start == checker_edge_size for the associated
* offset).
*
* Note that the following computation depends on the C99
* requirement that integer division discard any fraction
* (truncation towards zero) to function correctly. As we
* now require C99, this shouldn't be a problem, but noting
* it may save us some pain if we are ever obliged to support
* pre-C99 compilers again.
*/
base_count = dims[sel_offset] / (hsize_t)(checker_edge_size * 2);
if ((dims[sel_rank] % (hsize_t)(checker_edge_size * 2)) > 0) {
base_count++;
}
offset_count =
(hsize_t)((dims[sel_offset] - (hsize_t)checker_edge_size) / ((hsize_t)(checker_edge_size * 2)));
if (((dims[sel_rank] - (hsize_t)checker_edge_size) % ((hsize_t)(checker_edge_size * 2))) > 0) {
offset_count++;
}
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: base_count/offset_count = %d/%d.\n", fcnName, mpi_rank, base_count,
offset_count);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG */
/* Now set up the stride and block arrays, and portions of the start
* and count arrays that will not be altered during the selection of
* the checker board.
*/
i = 0;
while (i < ds_offset) {
/* these values should never be used */
start[i] = 0;
stride[i] = 0;
count[i] = 0;
block[i] = 0;
i++;
}
while (i < sel_offset) {
start[i] = sel_start[i];
stride[i] = 2 * dims[i];
count[i] = 1;
block[i] = 1;
i++;
}
while (i < test_max_rank) {
stride[i] = (hsize_t)(2 * checker_edge_size);
block[i] = (hsize_t)checker_edge_size;
i++;
}
i = 0;
do {
if (0 >= sel_offset) {
if (i == 0) {
start[0] = 0;
count[0] = base_count;
}
else {
start[0] = (hsize_t)checker_edge_size;
count[0] = offset_count;
}
}
j = 0;
do {
if (1 >= sel_offset) {
if (j == 0) {
start[1] = 0;
count[1] = base_count;
}
else {
start[1] = (hsize_t)checker_edge_size;
count[1] = offset_count;
}
}
k = 0;
do {
if (2 >= sel_offset) {
if (k == 0) {
start[2] = 0;
count[2] = base_count;
}
else {
start[2] = (hsize_t)checker_edge_size;
count[2] = offset_count;
}
}
l = 0;
do {
if (3 >= sel_offset) {
if (l == 0) {
start[3] = 0;
count[3] = base_count;
}
else {
start[3] = (hsize_t)checker_edge_size;
count[3] = offset_count;
}
}
m = 0;
do {
if (4 >= sel_offset) {
if (m == 0) {
start[4] = 0;
count[4] = base_count;
}
else {
start[4] = (hsize_t)checker_edge_size;
count[4] = offset_count;
}
}
if (((i + j + k + l + m) % 2) == 0) {
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s%d: *** first_selection = %d ***\n", fcnName, mpi_rank,
(int)first_selection);
HDfprintf(stdout, "%s:%d: i/j/k/l/m = %d/%d/%d/%d/%d\n", fcnName, mpi_rank, i,
j, k, l, m);
HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)start[0], (int)start[1], (int)start[2], (int)start[3],
(int)start[4]);
HDfprintf(stdout, "%s:%d: stride = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)stride[0], (int)stride[1], (int)stride[2], (int)stride[3],
(int)stride[4]);
HDfprintf(stdout, "%s:%d: count = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)count[0], (int)count[1], (int)count[2], (int)count[3],
(int)count[4]);
HDfprintf(stdout, "%s:%d: block = %d %d %d %d %d.\n", fcnName, mpi_rank,
(int)block[0], (int)block[1], (int)block[2], (int)block[3],
(int)block[4]);
HDfprintf(stdout, "%s:%d: n-cube extent dims = %d.\n", fcnName, mpi_rank,
H5Sget_simple_extent_ndims(tgt_sid));
HDfprintf(stdout, "%s:%d: selection rank = %d.\n", fcnName, mpi_rank,
sel_rank);
}
#endif
if (first_selection) {
first_selection = FALSE;
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_SET, &(start[ds_offset]),
&(stride[ds_offset]), &(count[ds_offset]),
&(block[ds_offset]));
VRFY((ret != FAIL), "H5Sselect_hyperslab(SET) succeeded");
}
else {
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_OR, &(start[ds_offset]),
&(stride[ds_offset]), &(count[ds_offset]),
&(block[ds_offset]));
VRFY((ret != FAIL), "H5Sselect_hyperslab(OR) succeeded");
}
}
m++;
} while ((m <= 1) && (4 >= sel_offset));
l++;
} while ((l <= 1) && (3 >= sel_offset));
k++;
} while ((k <= 1) && (2 >= sel_offset));
j++;
} while ((j <= 1) && (1 >= sel_offset));
i++;
} while ((i <= 1) && (0 >= sel_offset));
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(tgt_sid));
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG */
/* Clip the selection back to the dataspace proper. */
for (i = 0; i < test_max_rank; i++) {
start[i] = 0;
stride[i] = dims[i];
count[i] = 1;
block[i] = dims[i];
}
ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_AND, start, stride, count, block);
VRFY((ret != FAIL), "H5Sselect_hyperslab(AND) succeeded");
#if LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(tgt_sid));
HDfprintf(stdout, "%s%d: done.\n", fcnName, mpi_rank);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__SELECT_CHECKER_BOARD__DEBUG */
return;
} /* lower_dim_size_comp_test__select_checker_board() */
/****************************************************************
**
** lower_dim_size_comp_test__verify_data():
**
** Examine the supplied buffer to see if it contains the
** expected data. Return TRUE if it does, and FALSE
** otherwise.
**
** The supplied buffer is presumed to this process's slice
** of the target data set. Each such slice will be an
** n-cube of rank (rank -1) and the supplied edge_size with
** origin (mpi_rank, 0, ... , 0) in the target data set.
**
** Further, the buffer is presumed to be the result of reading
** or writing a checker board selection of an m (1 <= m <
** rank) dimensional slice through this processes slice
** of the target data set. Also, this slice must be parallel
** to the fastest changing indices.
**
** It is further presumed that the buffer was zeroed before
** the read/write, and that the full target data set (i.e.
** the buffer/data set for all processes) was initialized
** with the natural numbers listed in order from the origin
** along the fastest changing axis.
**
** Thus for a 20x10x10 dataset, the value stored in location
** (x, y, z) (assuming that z is the fastest changing index
** and x the slowest) is assumed to be:
**
** (10 * 10 * x) + (10 * y) + z
**
** Further, supposing that this is process 10, this process's
** slice of the dataset would be a 10 x 10 2-cube with origin
** (10, 0, 0) in the data set, and would be initialize (prior
** to the checkerboard selection) as follows:
**
** 1000, 1001, 1002, ... 1008, 1009
** 1010, 1011, 1012, ... 1018, 1019
** . . . . .
** . . . . .
** . . . . .
** 1090, 1091, 1092, ... 1098, 1099
**
** In the case of a read from the processors slice of another
** data set of different rank, the values expected will have
** to be adjusted accordingly. This is done via the
** first_expected_val parameter.
**
** Finally, the function presumes that the first element
** of the buffer resides either at the origin of either
** a selected or an unselected checker. (Translation:
** if partial checkers appear in the buffer, they will
** intersect the edges of the n-cube opposite the origin.)
**
****************************************************************/
#define LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG 0
static hbool_t
lower_dim_size_comp_test__verify_data(uint32_t *buf_ptr,
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
const int mpi_rank,
#endif /* LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG */
const int rank, const int edge_size, const int checker_edge_size,
uint32_t first_expected_val, hbool_t buf_starts_in_checker)
{
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
const char *fcnName = "lower_dim_size_comp_test__verify_data():";
#endif
hbool_t good_data = TRUE;
hbool_t in_checker;
hbool_t start_in_checker[5];
uint32_t expected_value;
uint32_t *val_ptr;
int i, j, k, l, m; /* to track position in n-cube */
int v, w, x, y, z; /* to track position in checker */
const int test_max_rank = 5; /* code changes needed if this is increased */
HDassert(buf_ptr != NULL);
HDassert(0 < rank);
HDassert(rank <= test_max_rank);
HDassert(edge_size >= 6);
HDassert(0 < checker_edge_size);
HDassert(checker_edge_size <= edge_size);
HDassert(test_max_rank <= LDSCT_DS_RANK);
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s mpi_rank = %d.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s rank = %d.\n", fcnName, rank);
HDfprintf(stdout, "%s edge_size = %d.\n", fcnName, edge_size);
HDfprintf(stdout, "%s checker_edge_size = %d.\n", fcnName, checker_edge_size);
HDfprintf(stdout, "%s first_expected_val = %d.\n", fcnName, (int)first_expected_val);
HDfprintf(stdout, "%s starts_in_checker = %d.\n", fcnName, (int)buf_starts_in_checker);
}
#endif
val_ptr = buf_ptr;
expected_value = first_expected_val;
i = 0;
v = 0;
start_in_checker[0] = buf_starts_in_checker;
do {
if (v >= checker_edge_size) {
start_in_checker[0] = !start_in_checker[0];
v = 0;
}
j = 0;
w = 0;
start_in_checker[1] = start_in_checker[0];
do {
if (w >= checker_edge_size) {
start_in_checker[1] = !start_in_checker[1];
w = 0;
}
k = 0;
x = 0;
start_in_checker[2] = start_in_checker[1];
do {
if (x >= checker_edge_size) {
start_in_checker[2] = !start_in_checker[2];
x = 0;
}
l = 0;
y = 0;
start_in_checker[3] = start_in_checker[2];
do {
if (y >= checker_edge_size) {
start_in_checker[3] = !start_in_checker[3];
y = 0;
}
m = 0;
z = 0;
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%d, %d, %d, %d, %d:", i, j, k, l, m);
}
#endif
in_checker = start_in_checker[3];
do {
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, " %d", (int)(*val_ptr));
}
#endif
if (z >= checker_edge_size) {
in_checker = !in_checker;
z = 0;
}
if (in_checker) {
if (*val_ptr != expected_value) {
good_data = FALSE;
}
/* zero out buffer for re-use */
*val_ptr = 0;
}
else if (*val_ptr != 0) {
good_data = FALSE;
/* zero out buffer for re-use */
*val_ptr = 0;
}
val_ptr++;
expected_value++;
m++;
z++;
} while ((rank >= (test_max_rank - 4)) && (m < edge_size));
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "\n");
}
#endif
l++;
y++;
} while ((rank >= (test_max_rank - 3)) && (l < edge_size));
k++;
x++;
} while ((rank >= (test_max_rank - 2)) && (k < edge_size));
j++;
w++;
} while ((rank >= (test_max_rank - 1)) && (j < edge_size));
i++;
v++;
} while ((rank >= test_max_rank) && (i < edge_size));
return (good_data);
} /* lower_dim_size_comp_test__verify_data() */
/*-------------------------------------------------------------------------
* Function: lower_dim_size_comp_test__run_test()
*
* Purpose: Verify that a bug in the computation of the size of the
* lower dimensions of a dataspace in H5S_obtain_datatype()
* has been corrected.
*
* Return: void
*
* Programmer: JRM -- 11/11/09
*
*-------------------------------------------------------------------------
*/
#define LDSCT_DS_RANK 5
static void
lower_dim_size_comp_test__run_test(const int chunk_edge_size, const hbool_t use_collective_io,
const hid_t dset_type)
{
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
const char *fcnName = "lower_dim_size_comp_test__run_test()";
int rank;
hsize_t dims[32];
hsize_t max_dims[32];
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
const char *filename;
hbool_t data_ok = FALSE;
hbool_t mis_match = FALSE;
int i;
int start_index;
int stop_index;
int mrc;
int mpi_rank;
int mpi_size;
MPI_Comm mpi_comm = MPI_COMM_NULL;
MPI_Info mpi_info = MPI_INFO_NULL;
hid_t fid; /* HDF5 file ID */
hid_t acc_tpl; /* File access templates */
hid_t xfer_plist = H5P_DEFAULT;
size_t small_ds_size;
size_t small_ds_slice_size;
size_t large_ds_size;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
size_t large_ds_slice_size;
#endif
uint32_t expected_value;
uint32_t *small_ds_buf_0 = NULL;
uint32_t *small_ds_buf_1 = NULL;
uint32_t *large_ds_buf_0 = NULL;
uint32_t *large_ds_buf_1 = NULL;
uint32_t *ptr_0;
uint32_t *ptr_1;
hsize_t small_chunk_dims[LDSCT_DS_RANK];
hsize_t large_chunk_dims[LDSCT_DS_RANK];
hsize_t small_dims[LDSCT_DS_RANK];
hsize_t large_dims[LDSCT_DS_RANK];
hsize_t start[LDSCT_DS_RANK];
hsize_t stride[LDSCT_DS_RANK];
hsize_t count[LDSCT_DS_RANK];
hsize_t block[LDSCT_DS_RANK];
hsize_t small_sel_start[LDSCT_DS_RANK];
hsize_t large_sel_start[LDSCT_DS_RANK];
hid_t full_mem_small_ds_sid;
hid_t full_file_small_ds_sid;
hid_t mem_small_ds_sid;
hid_t file_small_ds_sid;
hid_t full_mem_large_ds_sid;
hid_t full_file_large_ds_sid;
hid_t mem_large_ds_sid;
hid_t file_large_ds_sid;
hid_t small_ds_dcpl_id = H5P_DEFAULT;
hid_t large_ds_dcpl_id = H5P_DEFAULT;
hid_t small_dataset; /* Dataset ID */
hid_t large_dataset; /* Dataset ID */
htri_t check; /* Shape comparison return value */
herr_t ret; /* Generic return value */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
HDassert(mpi_size >= 1);
mpi_comm = MPI_COMM_WORLD;
mpi_info = MPI_INFO_NULL;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: chunk_edge_size = %d.\n", fcnName, mpi_rank, (int)chunk_edge_size);
HDfprintf(stdout, "%s:%d: use_collective_io = %d.\n", fcnName, mpi_rank, (int)use_collective_io);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
small_ds_size = (size_t)((mpi_size + 1) * 1 * 1 * 10 * 10);
small_ds_slice_size = (size_t)(1 * 1 * 10 * 10);
large_ds_size = (size_t)((mpi_size + 1) * 10 * 10 * 10 * 10);
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
large_ds_slice_size = (size_t)(10 * 10 * 10 * 10);
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: small ds size / slice size = %d / %d.\n", fcnName, mpi_rank,
(int)small_ds_size, (int)small_ds_slice_size);
HDfprintf(stdout, "%s:%d: large ds size / slice size = %d / %d.\n", fcnName, mpi_rank,
(int)large_ds_size, (int)large_ds_slice_size);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
/* Allocate buffers */
small_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * small_ds_size);
VRFY((small_ds_buf_0 != NULL), "malloc of small_ds_buf_0 succeeded");
small_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * small_ds_size);
VRFY((small_ds_buf_1 != NULL), "malloc of small_ds_buf_1 succeeded");
large_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * large_ds_size);
VRFY((large_ds_buf_0 != NULL), "malloc of large_ds_buf_0 succeeded");
large_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * large_ds_size);
VRFY((large_ds_buf_1 != NULL), "malloc of large_ds_buf_1 succeeded");
/* initialize the buffers */
ptr_0 = small_ds_buf_0;
ptr_1 = small_ds_buf_1;
for (i = 0; i < (int)small_ds_size; i++) {
*ptr_0 = (uint32_t)i;
*ptr_1 = 0;
ptr_0++;
ptr_1++;
}
ptr_0 = large_ds_buf_0;
ptr_1 = large_ds_buf_1;
for (i = 0; i < (int)large_ds_size; i++) {
*ptr_0 = (uint32_t)i;
*ptr_1 = 0;
ptr_0++;
ptr_1++;
}
/* get the file name */
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
HDassert(filename != NULL);
/* ----------------------------------------
* CREATE AN HDF5 FILE WITH PARALLEL ACCESS
* ---------------------------------------*/
/* setup file access template */
acc_tpl = create_faccess_plist(mpi_comm, mpi_info, facc_type);
VRFY((acc_tpl >= 0), "create_faccess_plist() succeeded");
/* create the file collectively */
fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((fid >= 0), "H5Fcreate succeeded");
MESG("File opened.");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose(acc_tpl) succeeded");
/* setup dims: */
small_dims[0] = (hsize_t)(mpi_size + 1);
small_dims[1] = 1;
small_dims[2] = 1;
small_dims[3] = 10;
small_dims[4] = 10;
large_dims[0] = (hsize_t)(mpi_size + 1);
large_dims[1] = 10;
large_dims[2] = 10;
large_dims[3] = 10;
large_dims[4] = 10;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: small_dims[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)small_dims[0],
(int)small_dims[1], (int)small_dims[2], (int)small_dims[3], (int)small_dims[4]);
HDfprintf(stdout, "%s:%d: large_dims[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)large_dims[0],
(int)large_dims[1], (int)large_dims[2], (int)large_dims[3], (int)large_dims[4]);
}
#endif
/* create dataspaces */
full_mem_small_ds_sid = H5Screate_simple(5, small_dims, NULL);
VRFY((full_mem_small_ds_sid != 0), "H5Screate_simple() full_mem_small_ds_sid succeeded");
full_file_small_ds_sid = H5Screate_simple(5, small_dims, NULL);
VRFY((full_file_small_ds_sid != 0), "H5Screate_simple() full_file_small_ds_sid succeeded");
mem_small_ds_sid = H5Screate_simple(5, small_dims, NULL);
VRFY((mem_small_ds_sid != 0), "H5Screate_simple() mem_small_ds_sid succeeded");
file_small_ds_sid = H5Screate_simple(5, small_dims, NULL);
VRFY((file_small_ds_sid != 0), "H5Screate_simple() file_small_ds_sid succeeded");
full_mem_large_ds_sid = H5Screate_simple(5, large_dims, NULL);
VRFY((full_mem_large_ds_sid != 0), "H5Screate_simple() full_mem_large_ds_sid succeeded");
full_file_large_ds_sid = H5Screate_simple(5, large_dims, NULL);
VRFY((full_file_large_ds_sid != 0), "H5Screate_simple() full_file_large_ds_sid succeeded");
mem_large_ds_sid = H5Screate_simple(5, large_dims, NULL);
VRFY((mem_large_ds_sid != 0), "H5Screate_simple() mem_large_ds_sid succeeded");
file_large_ds_sid = H5Screate_simple(5, large_dims, NULL);
VRFY((file_large_ds_sid != 0), "H5Screate_simple() file_large_ds_sid succeeded");
/* Select the entire extent of the full small ds dataspaces */
ret = H5Sselect_all(full_mem_small_ds_sid);
VRFY((ret != FAIL), "H5Sselect_all(full_mem_small_ds_sid) succeeded");
ret = H5Sselect_all(full_file_small_ds_sid);
VRFY((ret != FAIL), "H5Sselect_all(full_file_small_ds_sid) succeeded");
/* Select the entire extent of the full large ds dataspaces */
ret = H5Sselect_all(full_mem_large_ds_sid);
VRFY((ret != FAIL), "H5Sselect_all(full_mem_large_ds_sid) succeeded");
ret = H5Sselect_all(full_file_large_ds_sid);
VRFY((ret != FAIL), "H5Sselect_all(full_file_large_ds_sid) succeeded");
/* if chunk edge size is greater than zero, set up the small and
* large data set creation property lists to specify chunked
* datasets.
*/
if (chunk_edge_size > 0) {
small_chunk_dims[0] = (hsize_t)(1);
small_chunk_dims[1] = small_chunk_dims[2] = (hsize_t)1;
small_chunk_dims[3] = small_chunk_dims[4] = (hsize_t)chunk_edge_size;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: small chunk dims[] = %d %d %d %d %d\n", fcnName, mpi_rank,
(int)small_chunk_dims[0], (int)small_chunk_dims[1], (int)small_chunk_dims[2],
(int)small_chunk_dims[3], (int)small_chunk_dims[4]);
}
#endif
small_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((ret != FAIL), "H5Pcreate() small_ds_dcpl_id succeeded");
ret = H5Pset_layout(small_ds_dcpl_id, H5D_CHUNKED);
VRFY((ret != FAIL), "H5Pset_layout() small_ds_dcpl_id succeeded");
ret = H5Pset_chunk(small_ds_dcpl_id, 5, small_chunk_dims);
VRFY((ret != FAIL), "H5Pset_chunk() small_ds_dcpl_id succeeded");
large_chunk_dims[0] = (hsize_t)(1);
large_chunk_dims[1] = large_chunk_dims[2] = large_chunk_dims[3] = large_chunk_dims[4] =
(hsize_t)chunk_edge_size;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: large chunk dims[] = %d %d %d %d %d\n", fcnName, mpi_rank,
(int)large_chunk_dims[0], (int)large_chunk_dims[1], (int)large_chunk_dims[2],
(int)large_chunk_dims[3], (int)large_chunk_dims[4]);
}
#endif
large_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((ret != FAIL), "H5Pcreate() large_ds_dcpl_id succeeded");
ret = H5Pset_layout(large_ds_dcpl_id, H5D_CHUNKED);
VRFY((ret != FAIL), "H5Pset_layout() large_ds_dcpl_id succeeded");
ret = H5Pset_chunk(large_ds_dcpl_id, 5, large_chunk_dims);
VRFY((ret != FAIL), "H5Pset_chunk() large_ds_dcpl_id succeeded");
}
/* create the small dataset */
small_dataset = H5Dcreate2(fid, "small_dataset", dset_type, file_small_ds_sid, H5P_DEFAULT,
small_ds_dcpl_id, H5P_DEFAULT);
VRFY((ret >= 0), "H5Dcreate2() small_dataset succeeded");
/* create the large dataset */
large_dataset = H5Dcreate2(fid, "large_dataset", dset_type, file_large_ds_sid, H5P_DEFAULT,
large_ds_dcpl_id, H5P_DEFAULT);
VRFY((ret >= 0), "H5Dcreate2() large_dataset succeeded");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: small/large ds id = %d / %d.\n", fcnName, mpi_rank, (int)small_dataset,
(int)large_dataset);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
/* setup xfer property list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
if (!use_collective_io) {
ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
VRFY((ret >= 0), "H5Pset_dxpl_mpio_collective_opt() succeeded");
}
/* setup selection to write initial data to the small data sets */
start[0] = (hsize_t)(mpi_rank + 1);
start[1] = start[2] = start[3] = start[4] = 0;
stride[0] = (hsize_t)(2 * (mpi_size + 1));
stride[1] = stride[2] = 2;
stride[3] = stride[4] = 2 * 10;
count[0] = count[1] = count[2] = count[3] = count[4] = 1;
block[0] = block[1] = block[2] = 1;
block[3] = block[4] = 10;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: settings for small data set initialization.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s:%d: start[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)start[0],
(int)start[1], (int)start[2], (int)start[3], (int)start[4]);
HDfprintf(stdout, "%s:%d: stride[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)stride[0],
(int)stride[1], (int)stride[2], (int)stride[3], (int)stride[4]);
HDfprintf(stdout, "%s:%d: count[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)count[0],
(int)count[1], (int)count[2], (int)count[3], (int)count[4]);
HDfprintf(stdout, "%s:%d: block[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)block[0],
(int)block[1], (int)block[2], (int)block[3], (int)block[4]);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
/* setup selections for writing initial data to the small data set */
ret = H5Sselect_hyperslab(mem_small_ds_sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) succeeded");
ret = H5Sselect_hyperslab(file_small_ds_sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid, set) succeeded");
if (MAINPROCESS) { /* add an additional slice to the selections */
start[0] = 0;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: added settings for main process.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s:%d: start[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)start[0],
(int)start[1], (int)start[2], (int)start[3], (int)start[4]);
HDfprintf(stdout, "%s:%d: stride[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)stride[0],
(int)stride[1], (int)stride[2], (int)stride[3], (int)stride[4]);
HDfprintf(stdout, "%s:%d: count[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)count[0],
(int)count[1], (int)count[2], (int)count[3], (int)count[4]);
HDfprintf(stdout, "%s:%d: block[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)block[0],
(int)block[1], (int)block[2], (int)block[3], (int)block[4]);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
ret = H5Sselect_hyperslab(mem_small_ds_sid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, or) succeeded");
ret = H5Sselect_hyperslab(file_small_ds_sid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid, or) succeeded");
}
check = H5Sselect_valid(mem_small_ds_sid);
VRFY((check == TRUE), "H5Sselect_valid(mem_small_ds_sid) returns TRUE");
check = H5Sselect_valid(file_small_ds_sid);
VRFY((check == TRUE), "H5Sselect_valid(file_small_ds_sid) returns TRUE");
/* write the initial value of the small data set to file */
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: writing init value of small ds to file.\n", fcnName, mpi_rank);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
ret = H5Dwrite(small_dataset, dset_type, mem_small_ds_sid, file_small_ds_sid, xfer_plist, small_ds_buf_0);
VRFY((ret >= 0), "H5Dwrite() small_dataset initial write succeeded");
/* sync with the other processes before reading data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after small dataset writes");
/* read the small data set back to verify that it contains the
* expected data. Note that each process reads in the entire
* data set and verifies it.
*/
ret = H5Dread(small_dataset, H5T_NATIVE_UINT32, full_mem_small_ds_sid, full_file_small_ds_sid, xfer_plist,
small_ds_buf_1);
VRFY((ret >= 0), "H5Dread() small_dataset initial read succeeded");
/* sync with the other processes before checking data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after small dataset writes");
/* verify that the correct data was written to the small data set,
* and reset the buffer to zero in passing.
*/
expected_value = 0;
mis_match = FALSE;
ptr_1 = small_ds_buf_1;
i = 0;
for (i = 0; i < (int)small_ds_size; i++) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
*ptr_1 = (uint32_t)0;
ptr_1++;
expected_value++;
}
VRFY((mis_match == FALSE), "small ds init data good.");
/* setup selections for writing initial data to the large data set */
start[0] = (hsize_t)(mpi_rank + 1);
start[1] = start[2] = start[3] = start[4] = (hsize_t)0;
stride[0] = (hsize_t)(2 * (mpi_size + 1));
stride[1] = stride[2] = stride[3] = stride[4] = (hsize_t)(2 * 10);
count[0] = count[1] = count[2] = count[3] = count[4] = (hsize_t)1;
block[0] = (hsize_t)1;
block[1] = block[2] = block[3] = block[4] = (hsize_t)10;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: settings for large data set initialization.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s:%d: start[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)start[0],
(int)start[1], (int)start[2], (int)start[3], (int)start[4]);
HDfprintf(stdout, "%s:%d: stride[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)stride[0],
(int)stride[1], (int)stride[2], (int)stride[3], (int)stride[4]);
HDfprintf(stdout, "%s:%d: count[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)count[0],
(int)count[1], (int)count[2], (int)count[3], (int)count[4]);
HDfprintf(stdout, "%s:%d: block[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)block[0],
(int)block[1], (int)block[2], (int)block[3], (int)block[4]);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
ret = H5Sselect_hyperslab(mem_large_ds_sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_sid, set) succeeded");
ret = H5Sselect_hyperslab(file_large_ds_sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid, set) succeeded");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(mem_large_ds_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(mem_large_ds_sid));
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(file_large_ds_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(file_large_ds_sid));
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
if (MAINPROCESS) { /* add an additional slice to the selections */
start[0] = (hsize_t)0;
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: added settings for main process.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s:%d: start[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)start[0],
(int)start[1], (int)start[2], (int)start[3], (int)start[4]);
HDfprintf(stdout, "%s:%d: stride[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)stride[0],
(int)stride[1], (int)stride[2], (int)stride[3], (int)stride[4]);
HDfprintf(stdout, "%s:%d: count[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)count[0],
(int)count[1], (int)count[2], (int)count[3], (int)count[4]);
HDfprintf(stdout, "%s:%d: block[] = %d %d %d %d %d\n", fcnName, mpi_rank, (int)block[0],
(int)block[1], (int)block[2], (int)block[3], (int)block[4]);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
ret = H5Sselect_hyperslab(mem_large_ds_sid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_sid, or) succeeded");
ret = H5Sselect_hyperslab(file_large_ds_sid, H5S_SELECT_OR, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid, or) succeeded");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(mem_large_ds_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(mem_large_ds_sid));
HDfprintf(stdout, "%s%d: H5Sget_select_npoints(file_large_ds_sid) = %d.\n", fcnName, mpi_rank,
(int)H5Sget_select_npoints(file_large_ds_sid));
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
}
/* try clipping the selection back to the large dataspace proper */
start[0] = start[1] = start[2] = start[3] = start[4] = (hsize_t)0;
stride[0] = (hsize_t)(2 * (mpi_size + 1));
stride[1] = stride[2] = stride[3] = stride[4] = (hsize_t)(2 * 10);
count[0] = count[1] = count[2] = count[3] = count[4] = (hsize_t)1;
block[0] = (hsize_t)(mpi_size + 1);
block[1] = block[2] = block[3] = block[4] = (hsize_t)10;
ret = H5Sselect_hyperslab(mem_large_ds_sid, H5S_SELECT_AND, start, stride, count, block);
VRFY((ret != FAIL), "H5Sselect_hyperslab(mem_large_ds_sid, and) succeeded");
ret = H5Sselect_hyperslab(file_large_ds_sid, H5S_SELECT_AND, start, stride, count, block);
VRFY((ret != FAIL), "H5Sselect_hyperslab(file_large_ds_sid, and) succeeded");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
rank = H5Sget_simple_extent_dims(mem_large_ds_sid, dims, max_dims);
HDfprintf(stdout, "%s:%d: mem_large_ds_sid dims[%d] = %d %d %d %d %d\n", fcnName, mpi_rank, rank,
(int)dims[0], (int)dims[1], (int)dims[2], (int)dims[3], (int)dims[4]);
rank = H5Sget_simple_extent_dims(file_large_ds_sid, dims, max_dims);
HDfprintf(stdout, "%s:%d: file_large_ds_sid dims[%d] = %d %d %d %d %d\n", fcnName, mpi_rank, rank,
(int)dims[0], (int)dims[1], (int)dims[2], (int)dims[3], (int)dims[4]);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
check = H5Sselect_valid(mem_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_valid(mem_large_ds_sid) returns TRUE");
check = H5Sselect_valid(file_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_valid(file_large_ds_sid) returns TRUE");
/* write the initial value of the large data set to file */
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: writing init value of large ds to file.\n", fcnName, mpi_rank);
HDfprintf(stdout, "%s:%d: large_dataset = %d.\n", fcnName, mpi_rank, (int)large_dataset);
HDfprintf(stdout, "%s:%d: mem_large_ds_sid = %d, file_large_ds_sid = %d.\n", fcnName, mpi_rank,
(int)mem_large_ds_sid, (int)file_large_ds_sid);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
ret = H5Dwrite(large_dataset, dset_type, mem_large_ds_sid, file_large_ds_sid, xfer_plist, large_ds_buf_0);
if (ret < 0)
H5Eprint2(H5E_DEFAULT, stderr);
VRFY((ret >= 0), "H5Dwrite() large_dataset initial write succeeded");
/* sync with the other processes before checking data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after large dataset writes");
/* read the large data set back to verify that it contains the
* expected data. Note that each process reads in the entire
* data set.
*/
ret = H5Dread(large_dataset, H5T_NATIVE_UINT32, full_mem_large_ds_sid, full_file_large_ds_sid, xfer_plist,
large_ds_buf_1);
VRFY((ret >= 0), "H5Dread() large_dataset initial read succeeded");
/* verify that the correct data was written to the large data set.
* in passing, reset the buffer to zeros
*/
expected_value = 0;
mis_match = FALSE;
ptr_1 = large_ds_buf_1;
i = 0;
for (i = 0; i < (int)large_ds_size; i++) {
if (*ptr_1 != expected_value) {
mis_match = TRUE;
}
*ptr_1 = (uint32_t)0;
ptr_1++;
expected_value++;
}
VRFY((mis_match == FALSE), "large ds init data good.");
/***********************************/
/***** INITIALIZATION COMPLETE *****/
/***********************************/
/* read a checkerboard selection of the process slice of the
* small on disk data set into the process slice of the large
* in memory data set, and verify the data read.
*/
small_sel_start[0] = (hsize_t)(mpi_rank + 1);
small_sel_start[1] = small_sel_start[2] = small_sel_start[3] = small_sel_start[4] = 0;
lower_dim_size_comp_test__select_checker_board(mpi_rank, file_small_ds_sid,
/* tgt_rank = */ 5, small_dims,
/* checker_edge_size = */ 3,
/* sel_rank */ 2, small_sel_start);
expected_value =
(uint32_t)((small_sel_start[0] * small_dims[1] * small_dims[2] * small_dims[3] * small_dims[4]) +
(small_sel_start[1] * small_dims[2] * small_dims[3] * small_dims[4]) +
(small_sel_start[2] * small_dims[3] * small_dims[4]) +
(small_sel_start[3] * small_dims[4]) + (small_sel_start[4]));
large_sel_start[0] = (hsize_t)(mpi_rank + 1);
large_sel_start[1] = 5;
large_sel_start[2] = large_sel_start[3] = large_sel_start[4] = 0;
lower_dim_size_comp_test__select_checker_board(mpi_rank, mem_large_ds_sid,
/* tgt_rank = */ 5, large_dims,
/* checker_edge_size = */ 3,
/* sel_rank = */ 2, large_sel_start);
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(mem_large_ds_sid, file_small_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed (1)");
ret = H5Dread(small_dataset, H5T_NATIVE_UINT32, mem_large_ds_sid, file_small_ds_sid, xfer_plist,
large_ds_buf_1);
VRFY((ret >= 0), "H5Sread() slice from small ds succeeded.");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: H5Dread() returns.\n", fcnName, mpi_rank);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
/* verify that expected data is retrieved */
data_ok = TRUE;
start_index = (int)((large_sel_start[0] * large_dims[1] * large_dims[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[1] * large_dims[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[3] * large_dims[4]) + (large_sel_start[4]));
stop_index = start_index + (int)small_ds_slice_size;
HDassert(0 <= start_index);
HDassert(start_index < stop_index);
HDassert(stop_index <= (int)large_ds_size);
ptr_1 = large_ds_buf_1;
for (i = 0; i < start_index; i++) {
if (*ptr_1 != (uint32_t)0) {
data_ok = FALSE;
*ptr_1 = (uint32_t)0;
}
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from small ds data good(1).");
data_ok = lower_dim_size_comp_test__verify_data(ptr_1,
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
mpi_rank,
#endif /* LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG */
/* rank */ 2,
/* edge_size */ 10,
/* checker_edge_size */ 3, expected_value,
/* buf_starts_in_checker */ TRUE);
VRFY((data_ok == TRUE), "slice read from small ds data good(2).");
data_ok = TRUE;
ptr_1 += small_ds_slice_size;
for (i = stop_index; i < (int)large_ds_size; i++) {
if (*ptr_1 != (uint32_t)0) {
data_ok = FALSE;
*ptr_1 = (uint32_t)0;
}
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from small ds data good(3).");
/* read a checkerboard selection of a slice of the process slice of
* the large on disk data set into the process slice of the small
* in memory data set, and verify the data read.
*/
small_sel_start[0] = (hsize_t)(mpi_rank + 1);
small_sel_start[1] = small_sel_start[2] = small_sel_start[3] = small_sel_start[4] = 0;
lower_dim_size_comp_test__select_checker_board(mpi_rank, mem_small_ds_sid,
/* tgt_rank = */ 5, small_dims,
/* checker_edge_size = */ 3,
/* sel_rank */ 2, small_sel_start);
large_sel_start[0] = (hsize_t)(mpi_rank + 1);
large_sel_start[1] = 5;
large_sel_start[2] = large_sel_start[3] = large_sel_start[4] = 0;
lower_dim_size_comp_test__select_checker_board(mpi_rank, file_large_ds_sid,
/* tgt_rank = */ 5, large_dims,
/* checker_edge_size = */ 3,
/* sel_rank = */ 2, large_sel_start);
/* verify that H5Sselect_shape_same() reports the two
* selections as having the same shape.
*/
check = H5Sselect_shape_same(mem_small_ds_sid, file_large_ds_sid);
VRFY((check == TRUE), "H5Sselect_shape_same passed (2)");
ret = H5Dread(large_dataset, H5T_NATIVE_UINT32, mem_small_ds_sid, file_large_ds_sid, xfer_plist,
small_ds_buf_1);
VRFY((ret >= 0), "H5Sread() slice from large ds succeeded.");
#if LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: H5Dread() returns.\n", fcnName, mpi_rank);
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__RUN_TEST__DEBUG */
/* verify that expected data is retrieved */
data_ok = TRUE;
expected_value =
(uint32_t)((large_sel_start[0] * large_dims[1] * large_dims[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[1] * large_dims[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[2] * large_dims[3] * large_dims[4]) +
(large_sel_start[3] * large_dims[4]) + (large_sel_start[4]));
start_index = (int)(mpi_rank + 1) * (int)small_ds_slice_size;
stop_index = start_index + (int)small_ds_slice_size;
HDassert(0 <= start_index);
HDassert(start_index < stop_index);
HDassert(stop_index <= (int)small_ds_size);
ptr_1 = small_ds_buf_1;
for (i = 0; i < start_index; i++) {
if (*ptr_1 != (uint32_t)0) {
data_ok = FALSE;
*ptr_1 = (uint32_t)0;
}
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from large ds data good(1).");
data_ok = lower_dim_size_comp_test__verify_data(ptr_1,
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
mpi_rank,
#endif /* LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG */
/* rank */ 2,
/* edge_size */ 10,
/* checker_edge_size */ 3, expected_value,
/* buf_starts_in_checker */ TRUE);
VRFY((data_ok == TRUE), "slice read from large ds data good(2).");
data_ok = TRUE;
ptr_1 += small_ds_slice_size;
for (i = stop_index; i < (int)small_ds_size; i++) {
if (*ptr_1 != (uint32_t)0) {
#if LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG
if (mpi_rank == LOWER_DIM_SIZE_COMP_TEST_DEBUG_TARGET_RANK) {
HDfprintf(stdout, "%s:%d: unexpected value at index %d: %d.\n", fcnName, mpi_rank, (int)i,
(int)(*ptr_1));
}
#endif /* LOWER_DIM_SIZE_COMP_TEST__VERIFY_DATA__DEBUG */
data_ok = FALSE;
*ptr_1 = (uint32_t)0;
}
ptr_1++;
}
VRFY((data_ok == TRUE), "slice read from large ds data good(3).");
/* Close dataspaces */
ret = H5Sclose(full_mem_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_mem_small_ds_sid) succeeded");
ret = H5Sclose(full_file_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_file_small_ds_sid) succeeded");
ret = H5Sclose(mem_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(mem_small_ds_sid) succeeded");
ret = H5Sclose(file_small_ds_sid);
VRFY((ret != FAIL), "H5Sclose(file_small_ds_sid) succeeded");
ret = H5Sclose(full_mem_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_mem_large_ds_sid) succeeded");
ret = H5Sclose(full_file_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(full_file_large_ds_sid) succeeded");
ret = H5Sclose(mem_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(mem_large_ds_sid) succeeded");
ret = H5Sclose(file_large_ds_sid);
VRFY((ret != FAIL), "H5Sclose(file_large_ds_sid) succeeded");
/* Close Datasets */
ret = H5Dclose(small_dataset);
VRFY((ret != FAIL), "H5Dclose(small_dataset) succeeded");
ret = H5Dclose(large_dataset);
VRFY((ret != FAIL), "H5Dclose(large_dataset) succeeded");
/* close the file collectively */
MESG("about to close file.");
ret = H5Fclose(fid);
VRFY((ret != FAIL), "file close succeeded");
/* Free memory buffers */
if (small_ds_buf_0 != NULL)
HDfree(small_ds_buf_0);
if (small_ds_buf_1 != NULL)
HDfree(small_ds_buf_1);
if (large_ds_buf_0 != NULL)
HDfree(large_ds_buf_0);
if (large_ds_buf_1 != NULL)
HDfree(large_ds_buf_1);
return;
} /* lower_dim_size_comp_test__run_test() */
/*-------------------------------------------------------------------------
* Function: lower_dim_size_comp_test()
*
* Purpose: Test to see if an error in the computation of the size
* of the lower dimensions in H5S_obtain_datatype() has
* been corrected.
*
* Return: void
*
* Programmer: JRM -- 11/11/09
*
*-------------------------------------------------------------------------
*/
void
lower_dim_size_comp_test(void)
{
/* const char *fcnName = "lower_dim_size_comp_test()"; */
int chunk_edge_size = 0;
int use_collective_io;
int mpi_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned));
for (use_collective_io = 0; use_collective_io <= 1; use_collective_io++) {
chunk_edge_size = 0;
lower_dim_size_comp_test__run_test(chunk_edge_size, (hbool_t)use_collective_io, H5T_NATIVE_UINT);
chunk_edge_size = 5;
lower_dim_size_comp_test__run_test(chunk_edge_size, (hbool_t)use_collective_io, H5T_NATIVE_UINT);
} /* end for */
return;
} /* lower_dim_size_comp_test() */
/*-------------------------------------------------------------------------
* Function: link_chunk_collective_io_test()
*
* Purpose: Test to verify that an error in MPI type management in
* H5D_link_chunk_collective_io() has been corrected.
* In this bug, we used to free MPI types regardless of
* whether they were basic or derived.
*
* This test is based on a bug report kindly provided by
* Rob Latham of the MPICH team and ANL.
*
* The basic thrust of the test is to cause a process
* to participate in a collective I/O in which it:
*
* 1) Reads or writes exactly one chunk,
*
* 2) Has no in memory buffer for any other chunk.
*
* The test differers from Rob Latham's bug report in
* that is runs with an arbitrary number of proceeses,
* and uses a 1 dimensional dataset.
*
* Return: void
*
* Programmer: JRM -- 12/16/09
*
*-------------------------------------------------------------------------
*/
#define LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE 16
void
link_chunk_collective_io_test(void)
{
/* const char *fcnName = "link_chunk_collective_io_test()"; */
const char *filename;
hbool_t mis_match = FALSE;
int i;
int mrc;
int mpi_rank;
int mpi_size;
MPI_Comm mpi_comm = MPI_COMM_WORLD;
MPI_Info mpi_info = MPI_INFO_NULL;
hsize_t count[1] = {1};
hsize_t stride[1] = {2 * LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE};
hsize_t block[1] = {LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE};
hsize_t start[1];
hsize_t dims[1];
hsize_t chunk_dims[1] = {LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE};
herr_t ret; /* Generic return value */
hid_t file_id;
hid_t acc_tpl;
hid_t dset_id;
hid_t file_ds_sid;
hid_t write_mem_ds_sid;
hid_t read_mem_ds_sid;
hid_t ds_dcpl_id;
hid_t xfer_plist;
double diff;
double expected_value;
double local_data_written[LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE];
double local_data_read[LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE];
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
if (MAINPROCESS) {
puts("SKIPPED");
printf(" API functions for basic file or dataset aren't supported with this connector\n");
fflush(stdout);
}
return;
}
HDassert(mpi_size > 0);
/* get the file name */
filename = (const char *)PARATESTFILE /* GetTestParameters() */;
HDassert(filename != NULL);
/* setup file access template */
acc_tpl = create_faccess_plist(mpi_comm, mpi_info, facc_type);
VRFY((acc_tpl >= 0), "create_faccess_plist() succeeded");
/* create the file collectively */
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
VRFY((file_id >= 0), "H5Fcreate succeeded");
MESG("File opened.");
/* Release file-access template */
ret = H5Pclose(acc_tpl);
VRFY((ret >= 0), "H5Pclose(acc_tpl) succeeded");
/* setup dims */
dims[0] = ((hsize_t)mpi_size) * ((hsize_t)(LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE));
/* setup mem and file dataspaces */
write_mem_ds_sid = H5Screate_simple(1, chunk_dims, NULL);
VRFY((write_mem_ds_sid != 0), "H5Screate_simple() write_mem_ds_sid succeeded");
read_mem_ds_sid = H5Screate_simple(1, chunk_dims, NULL);
VRFY((read_mem_ds_sid != 0), "H5Screate_simple() read_mem_ds_sid succeeded");
file_ds_sid = H5Screate_simple(1, dims, NULL);
VRFY((file_ds_sid != 0), "H5Screate_simple() file_ds_sid succeeded");
/* setup data set creation property list */
ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
VRFY((ds_dcpl_id != FAIL), "H5Pcreate() ds_dcpl_id succeeded");
ret = H5Pset_layout(ds_dcpl_id, H5D_CHUNKED);
VRFY((ret != FAIL), "H5Pset_layout() ds_dcpl_id succeeded");
ret = H5Pset_chunk(ds_dcpl_id, 1, chunk_dims);
VRFY((ret != FAIL), "H5Pset_chunk() small_ds_dcpl_id succeeded");
/* create the data set */
dset_id =
H5Dcreate2(file_id, "dataset", H5T_NATIVE_DOUBLE, file_ds_sid, H5P_DEFAULT, ds_dcpl_id, H5P_DEFAULT);
VRFY((dset_id >= 0), "H5Dcreate2() dataset succeeded");
/* close the dataset creation property list */
ret = H5Pclose(ds_dcpl_id);
VRFY((ret >= 0), "H5Pclose(ds_dcpl_id) succeeded");
/* setup local data */
expected_value = (double)(LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE) * (double)(mpi_rank);
for (i = 0; i < LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE; i++) {
local_data_written[i] = expected_value;
local_data_read[i] = 0.0;
expected_value += 1.0;
}
/* select the file and mem spaces */
start[0] = (hsize_t)(mpi_rank * LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE);
ret = H5Sselect_hyperslab(file_ds_sid, H5S_SELECT_SET, start, stride, count, block);
VRFY((ret >= 0), "H5Sselect_hyperslab(file_ds_sid, set) succeeded");
ret = H5Sselect_all(write_mem_ds_sid);
VRFY((ret != FAIL), "H5Sselect_all(mem_ds_sid) succeeded");
/* Note that we use NO SELECTION on the read memory dataspace */
/* setup xfer property list */
xfer_plist = H5Pcreate(H5P_DATASET_XFER);
VRFY((xfer_plist >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
/* write the data set */
ret = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, write_mem_ds_sid, file_ds_sid, xfer_plist, local_data_written);
VRFY((ret >= 0), "H5Dwrite() dataset initial write succeeded");
/* sync with the other processes before checking data */
mrc = MPI_Barrier(MPI_COMM_WORLD);
VRFY((mrc == MPI_SUCCESS), "Sync after dataset write");
/* read this processes slice of the dataset back in */
ret = H5Dread(dset_id, H5T_NATIVE_DOUBLE, read_mem_ds_sid, file_ds_sid, xfer_plist, local_data_read);
VRFY((ret >= 0), "H5Dread() dataset read succeeded");
/* close the xfer property list */
ret = H5Pclose(xfer_plist);
VRFY((ret >= 0), "H5Pclose(xfer_plist) succeeded");
/* verify the data */
mis_match = FALSE;
for (i = 0; i < LINK_CHUNK_COLLECTIVE_IO_TEST_CHUNK_SIZE; i++) {
diff = local_data_written[i] - local_data_read[i];
diff = fabs(diff);
if (diff >= 0.001) {
mis_match = TRUE;
}
}
VRFY((mis_match == FALSE), "dataset data good.");
/* Close dataspaces */
ret = H5Sclose(write_mem_ds_sid);
VRFY((ret != FAIL), "H5Sclose(write_mem_ds_sid) succeeded");
ret = H5Sclose(read_mem_ds_sid);
VRFY((ret != FAIL), "H5Sclose(read_mem_ds_sid) succeeded");
ret = H5Sclose(file_ds_sid);
VRFY((ret != FAIL), "H5Sclose(file_ds_sid) succeeded");
/* Close Dataset */
ret = H5Dclose(dset_id);
VRFY((ret != FAIL), "H5Dclose(dset_id) succeeded");
/* close the file collectively */
ret = H5Fclose(file_id);
VRFY((ret != FAIL), "file close succeeded");
return;
} /* link_chunk_collective_io_test() */
+1007
View File
@@ -0,0 +1,1007 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Main driver of the Parallel HDF5 tests
*/
#include "hdf5.h"
#include "testphdf5.h"
#ifndef PATH_MAX
#define PATH_MAX 512
#endif /* !PATH_MAX */
/* global variables */
int dim0;
int dim1;
int chunkdim0;
int chunkdim1;
int nerrors = 0; /* errors count */
int ndatasets = 300; /* number of datasets to create*/
int ngroups = 512; /* number of groups to create in root
* group. */
int facc_type = FACC_MPIO; /*Test file access type */
int dxfer_coll_type = DXFER_COLLECTIVE_IO;
H5E_auto2_t old_func; /* previous error handler */
void *old_client_data; /* previous error handler arg.*/
/* other option flags */
/* FILENAME and filenames must have the same number of names.
* Use PARATESTFILE in general and use a separated filename only if the file
* created in one test is accessed by a different test.
* filenames[0] is reserved as the file name for PARATESTFILE.
*/
#define NFILENAME 2
/* #define PARATESTFILE filenames[0] */
const char *FILENAME[NFILENAME] = {"ParaTest.h5", NULL};
char filenames[NFILENAME][PATH_MAX];
hid_t fapl; /* file access property list */
#ifdef USE_PAUSE
/* pause the process for a moment to allow debugger to attach if desired. */
/* Will pause more if greenlight file is not persent but will eventually */
/* continue. */
#include <sys/types.h>
#include <sys/stat.h>
void
pause_proc(void)
{
int pid;
h5_stat_t statbuf;
char greenlight[] = "go";
int maxloop = 10;
int loops = 0;
int time_int = 10;
/* mpi variables */
int mpi_size, mpi_rank;
int mpi_namelen;
char mpi_name[MPI_MAX_PROCESSOR_NAME];
pid = getpid();
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
MPI_Get_processor_name(mpi_name, &mpi_namelen);
if (MAINPROCESS)
while ((HDstat(greenlight, &statbuf) == -1) && loops < maxloop) {
if (!loops++) {
HDprintf("Proc %d (%*s, %d): to debug, attach %d\n", mpi_rank, mpi_namelen, mpi_name, pid,
pid);
}
HDprintf("waiting(%ds) for file %s ...\n", time_int, greenlight);
HDfflush(stdout);
HDsleep(time_int);
}
MPI_Barrier(MPI_COMM_WORLD);
}
/* Use the Profile feature of MPI to call the pause_proc() */
int
MPI_Init(int *argc, char ***argv)
{
int ret_code;
ret_code = PMPI_Init(argc, argv);
pause_proc();
return (ret_code);
}
#endif /* USE_PAUSE */
/*
* Show command usage
*/
static void
usage(void)
{
HDprintf(" [-r] [-w] [-m<n_datasets>] [-n<n_groups>] "
"[-o] [-f <prefix>] [-d <dim0> <dim1>]\n");
HDprintf("\t-m<n_datasets>"
"\tset number of datasets for the multiple dataset test\n");
HDprintf("\t-n<n_groups>"
"\tset number of groups for the multiple group test\n");
#if 0
HDprintf("\t-f <prefix>\tfilename prefix\n");
#endif
HDprintf("\t-2\t\tuse Split-file together with MPIO\n");
HDprintf("\t-d <factor0> <factor1>\tdataset dimensions factors. Defaults (%d,%d)\n", ROW_FACTOR,
COL_FACTOR);
HDprintf("\t-c <dim0> <dim1>\tdataset chunk dimensions. Defaults (dim0/10,dim1/10)\n");
HDprintf("\n");
}
/*
* parse the command line options
*/
static int
parse_options(int argc, char **argv)
{
int mpi_size, mpi_rank; /* mpi variables */
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* setup default chunk-size. Make sure sizes are > 0 */
chunkdim0 = (dim0 + 9) / 10;
chunkdim1 = (dim1 + 9) / 10;
while (--argc) {
if (**(++argv) != '-') {
break;
}
else {
switch (*(*argv + 1)) {
case 'm':
ndatasets = atoi((*argv + 1) + 1);
if (ndatasets < 0) {
nerrors++;
return (1);
}
break;
case 'n':
ngroups = atoi((*argv + 1) + 1);
if (ngroups < 0) {
nerrors++;
return (1);
}
break;
#if 0
case 'f': if (--argc < 1) {
nerrors++;
return(1);
}
if (**(++argv) == '-') {
nerrors++;
return(1);
}
paraprefix = *argv;
break;
#endif
case 'i': /* Collective MPI-IO access with independent IO */
dxfer_coll_type = DXFER_INDEPENDENT_IO;
break;
case '2': /* Use the split-file driver with MPIO access */
/* Can use $HDF5_METAPREFIX to define the */
/* meta-file-prefix. */
facc_type = FACC_MPIO | FACC_SPLIT;
break;
case 'd': /* dimensizes */
if (--argc < 2) {
nerrors++;
return (1);
}
dim0 = atoi(*(++argv)) * mpi_size;
argc--;
dim1 = atoi(*(++argv)) * mpi_size;
/* set default chunkdim sizes too */
chunkdim0 = (dim0 + 9) / 10;
chunkdim1 = (dim1 + 9) / 10;
break;
case 'c': /* chunk dimensions */
if (--argc < 2) {
nerrors++;
return (1);
}
chunkdim0 = atoi(*(++argv));
argc--;
chunkdim1 = atoi(*(++argv));
break;
case 'h': /* print help message--return with nerrors set */
return (1);
default:
HDprintf("Illegal option(%s)\n", *argv);
nerrors++;
return (1);
}
}
} /*while*/
/* check validity of dimension and chunk sizes */
if (dim0 <= 0 || dim1 <= 0) {
HDprintf("Illegal dim sizes (%d, %d)\n", dim0, dim1);
nerrors++;
return (1);
}
if (chunkdim0 <= 0 || chunkdim1 <= 0) {
HDprintf("Illegal chunkdim sizes (%d, %d)\n", chunkdim0, chunkdim1);
nerrors++;
return (1);
}
/* Make sure datasets can be divided into equal portions by the processes */
if ((dim0 % mpi_size) || (dim1 % mpi_size)) {
if (MAINPROCESS)
HDprintf("dim0(%d) and dim1(%d) must be multiples of processes(%d)\n", dim0, dim1, mpi_size);
nerrors++;
return (1);
}
/* compose the test filenames */
{
int i, n;
n = sizeof(FILENAME) / sizeof(FILENAME[0]) - 1; /* exclude the NULL */
for (i = 0; i < n; i++)
strncpy(filenames[i], FILENAME[i], PATH_MAX);
#if 0 /* no support for VFDs right now */
if (h5_fixname(FILENAME[i], fapl, filenames[i], PATH_MAX) == NULL) {
HDprintf("h5_fixname failed\n");
nerrors++;
return (1);
}
#endif
if (MAINPROCESS) {
HDprintf("Test filenames are:\n");
for (i = 0; i < n; i++)
HDprintf(" %s\n", filenames[i]);
}
}
return (0);
}
/*
* Create the appropriate File access property list
*/
hid_t
create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type)
{
hid_t ret_pl = -1;
herr_t ret; /* generic return value */
int mpi_rank; /* mpi variables */
/* need the rank for error checking macros */
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((ret_pl >= 0), "H5P_FILE_ACCESS");
if (l_facc_type == FACC_DEFAULT)
return (ret_pl);
if (l_facc_type == FACC_MPIO) {
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(ret_pl, comm, info);
VRFY((ret >= 0), "");
ret = H5Pset_all_coll_metadata_ops(ret_pl, TRUE);
VRFY((ret >= 0), "");
ret = H5Pset_coll_metadata_write(ret_pl, TRUE);
VRFY((ret >= 0), "");
return (ret_pl);
}
if (l_facc_type == (FACC_MPIO | FACC_SPLIT)) {
hid_t mpio_pl;
mpio_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((mpio_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_mpio(mpio_pl, comm, info);
VRFY((ret >= 0), "");
/* setup file access template */
ret_pl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((ret_pl >= 0), "");
/* set Parallel access with communicator */
ret = H5Pset_fapl_split(ret_pl, ".meta", mpio_pl, ".raw", mpio_pl);
VRFY((ret >= 0), "H5Pset_fapl_split succeeded");
H5Pclose(mpio_pl);
return (ret_pl);
}
/* unknown file access types */
return (ret_pl);
}
int
main(int argc, char **argv)
{
int mpi_size, mpi_rank; /* mpi variables */
herr_t ret;
#if 0
H5Ptest_param_t ndsets_params, ngroups_params;
H5Ptest_param_t collngroups_params;
H5Ptest_param_t io_mode_confusion_params;
H5Ptest_param_t rr_obj_flush_confusion_params;
#endif
#ifndef H5_HAVE_WIN32_API
/* Un-buffer the stdout and stderr */
HDsetbuf(stderr, NULL);
HDsetbuf(stdout, NULL);
#endif
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
dim0 = ROW_FACTOR * mpi_size;
dim1 = COL_FACTOR * mpi_size;
if (MAINPROCESS) {
HDprintf("===================================\n");
HDprintf("PHDF5 TESTS START\n");
HDprintf("===================================\n");
}
/* Attempt to turn off atexit post processing so that in case errors
* happen during the test and the process is aborted, it will not get
* hang in the atexit post processing in which it may try to make MPI
* calls. By then, MPI calls may not work.
*/
if (H5dont_atexit() < 0) {
HDprintf("Failed to turn off atexit processing. Continue.\n");
};
H5open();
/* h5_show_hostname(); */
#if 0
HDmemset(filenames, 0, sizeof(filenames));
for (int i = 0; i < NFILENAME; i++) {
if (NULL == (filenames[i] = HDmalloc(PATH_MAX))) {
HDprintf("couldn't allocate filename array\n");
MPI_Abort(MPI_COMM_WORLD, -1);
}
}
#endif
/* Set up file access property list with parallel I/O access */
fapl = H5Pcreate(H5P_FILE_ACCESS);
VRFY((fapl >= 0), "H5Pcreate succeeded");
vol_cap_flags_g = H5VL_CAP_FLAG_NONE;
/* Get the capability flag of the VOL connector being used */
ret = H5Pget_vol_cap_flags(fapl, &vol_cap_flags_g);
VRFY((ret >= 0), "H5Pget_vol_cap_flags succeeded");
/* Initialize testing framework */
/* TestInit(argv[0], usage, parse_options); */
if (parse_options(argc, argv)) {
usage();
return 1;
}
/* Tests are generally arranged from least to most complexity... */
#if 0
AddTest("mpiodup", test_fapl_mpio_dup, NULL,
"fapl_mpio duplicate", NULL);
#endif
if (MAINPROCESS) {
printf("fapl_mpio duplicate\n");
fflush(stdout);
}
test_fapl_mpio_dup();
#if 0
AddTest("split", test_split_comm_access, NULL,
"dataset using split communicators", PARATESTFILE);
AddTest("props", test_file_properties, NULL,
"Coll Metadata file property settings", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("dataset using split communicators\n");
fflush(stdout);
}
test_split_comm_access();
if (MAINPROCESS) {
printf("Coll Metadata file property settings\n");
fflush(stdout);
}
test_file_properties();
#if 0
AddTest("idsetw", dataset_writeInd, NULL,
"dataset independent write", PARATESTFILE);
AddTest("idsetr", dataset_readInd, NULL,
"dataset independent read", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("dataset independent write\n");
fflush(stdout);
}
dataset_writeInd();
if (MAINPROCESS) {
printf("dataset independent read\n");
fflush(stdout);
}
dataset_readInd();
#if 0
AddTest("cdsetw", dataset_writeAll, NULL,
"dataset collective write", PARATESTFILE);
AddTest("cdsetr", dataset_readAll, NULL,
"dataset collective read", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("dataset collective write\n");
fflush(stdout);
}
dataset_writeAll();
if (MAINPROCESS) {
printf("dataset collective read\n");
fflush(stdout);
}
dataset_readAll();
#if 0
AddTest("eidsetw", extend_writeInd, NULL,
"extendible dataset independent write", PARATESTFILE);
AddTest("eidsetr", extend_readInd, NULL,
"extendible dataset independent read", PARATESTFILE);
AddTest("ecdsetw", extend_writeAll, NULL,
"extendible dataset collective write", PARATESTFILE);
AddTest("ecdsetr", extend_readAll, NULL,
"extendible dataset collective read", PARATESTFILE);
AddTest("eidsetw2", extend_writeInd2, NULL,
"extendible dataset independent write #2", PARATESTFILE);
AddTest("selnone", none_selection_chunk, NULL,
"chunked dataset with none-selection", PARATESTFILE);
AddTest("calloc", test_chunk_alloc, NULL,
"parallel extend Chunked allocation on serial file", PARATESTFILE);
AddTest("fltread", test_filter_read, NULL,
"parallel read of dataset written serially with filters", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("extendible dataset independent write\n");
fflush(stdout);
}
extend_writeInd();
if (MAINPROCESS) {
printf("extendible dataset independent read\n");
fflush(stdout);
}
extend_readInd();
if (MAINPROCESS) {
printf("extendible dataset collective write\n");
fflush(stdout);
}
extend_writeAll();
if (MAINPROCESS) {
printf("extendible dataset collective read\n");
fflush(stdout);
}
extend_readAll();
if (MAINPROCESS) {
printf("extendible dataset independent write #2\n");
fflush(stdout);
}
extend_writeInd2();
if (MAINPROCESS) {
printf("chunked dataset with none-selection\n");
fflush(stdout);
}
none_selection_chunk();
if (MAINPROCESS) {
printf("parallel extend Chunked allocation on serial file\n");
fflush(stdout);
}
test_chunk_alloc();
if (MAINPROCESS) {
printf("parallel read of dataset written serially with filters\n");
fflush(stdout);
}
test_filter_read();
#ifdef H5_HAVE_FILTER_DEFLATE
#if 0
AddTest("cmpdsetr", compress_readAll, NULL,
"compressed dataset collective read", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("compressed dataset collective read\n");
fflush(stdout);
}
compress_readAll();
#endif /* H5_HAVE_FILTER_DEFLATE */
#if 0
AddTest("zerodsetr", zero_dim_dset, NULL,
"zero dim dset", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("zero dim dset\n");
fflush(stdout);
}
zero_dim_dset();
#if 0
ndsets_params.name = PARATESTFILE;
ndsets_params.count = ndatasets;
AddTest("ndsetw", multiple_dset_write, NULL,
"multiple datasets write", &ndsets_params);
#endif
if (MAINPROCESS) {
printf("multiple datasets write\n");
fflush(stdout);
}
multiple_dset_write();
#if 0
ngroups_params.name = PARATESTFILE;
ngroups_params.count = ngroups;
AddTest("ngrpw", multiple_group_write, NULL,
"multiple groups write", &ngroups_params);
AddTest("ngrpr", multiple_group_read, NULL,
"multiple groups read", &ngroups_params);
#endif
if (MAINPROCESS) {
printf("multiple groups write\n");
fflush(stdout);
}
multiple_group_write();
if (MAINPROCESS) {
printf("multiple groups read\n");
fflush(stdout);
}
multiple_group_read();
#if 0
AddTest("compact", compact_dataset, NULL,
"compact dataset test", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("compact dataset test\n");
fflush(stdout);
}
compact_dataset();
#if 0
collngroups_params.name = PARATESTFILE;
collngroups_params.count = ngroups;
/* combined cngrpw and ingrpr tests because ingrpr reads file created by cngrpw. */
AddTest("cngrpw-ingrpr", collective_group_write_independent_group_read, NULL,
"collective grp/dset write - independent grp/dset read",
&collngroups_params);
#ifndef H5_HAVE_WIN32_API
AddTest("bigdset", big_dataset, NULL,
"big dataset test", PARATESTFILE);
#else
HDprintf("big dataset test will be skipped on Windows (JIRA HDDFV-8064)\n");
#endif
#endif
if (MAINPROCESS) {
printf("collective grp/dset write - independent grp/dset read\n");
fflush(stdout);
}
collective_group_write_independent_group_read();
if (MAINPROCESS) {
printf("big dataset test\n");
fflush(stdout);
}
big_dataset();
#if 0
AddTest("fill", dataset_fillvalue, NULL,
"dataset fill value", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("dataset fill value\n");
fflush(stdout);
}
dataset_fillvalue();
#if 0
AddTest("cchunk1",
coll_chunk1,NULL, "simple collective chunk io",PARATESTFILE);
AddTest("cchunk2",
coll_chunk2,NULL, "noncontiguous collective chunk io",PARATESTFILE);
AddTest("cchunk3",
coll_chunk3,NULL, "multi-chunk collective chunk io",PARATESTFILE);
AddTest("cchunk4",
coll_chunk4,NULL, "collective chunk io with partial non-selection ",PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("simple collective chunk io\n");
fflush(stdout);
}
coll_chunk1();
if (MAINPROCESS) {
printf("noncontiguous collective chunk io\n");
fflush(stdout);
}
coll_chunk2();
if (MAINPROCESS) {
printf("multi-chunk collective chunk io\n");
fflush(stdout);
}
coll_chunk3();
if (MAINPROCESS) {
printf("collective chunk io with partial non-selection\n");
fflush(stdout);
}
coll_chunk4();
if ((mpi_size < 3) && MAINPROCESS) {
HDprintf("Collective chunk IO optimization APIs ");
HDprintf("needs at least 3 processes to participate\n");
HDprintf("Collective chunk IO API tests will be skipped \n");
}
#if 0
AddTest((mpi_size <3)? "-cchunk5":"cchunk5" ,
coll_chunk5,NULL,
"linked chunk collective IO without optimization",PARATESTFILE);
AddTest((mpi_size < 3)? "-cchunk6" : "cchunk6",
coll_chunk6,NULL,
"multi-chunk collective IO with direct request",PARATESTFILE);
AddTest((mpi_size < 3)? "-cchunk7" : "cchunk7",
coll_chunk7,NULL,
"linked chunk collective IO with optimization",PARATESTFILE);
AddTest((mpi_size < 3)? "-cchunk8" : "cchunk8",
coll_chunk8,NULL,
"linked chunk collective IO transferring to multi-chunk",PARATESTFILE);
AddTest((mpi_size < 3)? "-cchunk9" : "cchunk9",
coll_chunk9,NULL,
"multiple chunk collective IO with optimization",PARATESTFILE);
AddTest((mpi_size < 3)? "-cchunk10" : "cchunk10",
coll_chunk10,NULL,
"multiple chunk collective IO transferring to independent IO",PARATESTFILE);
#endif
if (mpi_size >= 3) {
if (MAINPROCESS) {
printf("linked chunk collective IO without optimization\n");
fflush(stdout);
}
coll_chunk5();
if (MAINPROCESS) {
printf("multi-chunk collective IO with direct request\n");
fflush(stdout);
}
coll_chunk6();
if (MAINPROCESS) {
printf("linked chunk collective IO with optimization\n");
fflush(stdout);
}
coll_chunk7();
if (MAINPROCESS) {
printf("linked chunk collective IO transferring to multi-chunk\n");
fflush(stdout);
}
coll_chunk8();
if (MAINPROCESS) {
printf("multiple chunk collective IO with optimization\n");
fflush(stdout);
}
coll_chunk9();
if (MAINPROCESS) {
printf("multiple chunk collective IO transferring to independent IO\n");
fflush(stdout);
}
coll_chunk10();
}
#if 0
/* irregular collective IO tests*/
AddTest("ccontw",
coll_irregular_cont_write,NULL,
"collective irregular contiguous write",PARATESTFILE);
AddTest("ccontr",
coll_irregular_cont_read,NULL,
"collective irregular contiguous read",PARATESTFILE);
AddTest("cschunkw",
coll_irregular_simple_chunk_write,NULL,
"collective irregular simple chunk write",PARATESTFILE);
AddTest("cschunkr",
coll_irregular_simple_chunk_read,NULL,
"collective irregular simple chunk read",PARATESTFILE);
AddTest("ccchunkw",
coll_irregular_complex_chunk_write,NULL,
"collective irregular complex chunk write",PARATESTFILE);
AddTest("ccchunkr",
coll_irregular_complex_chunk_read,NULL,
"collective irregular complex chunk read",PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("collective irregular contiguous write\n");
fflush(stdout);
}
coll_irregular_cont_write();
if (MAINPROCESS) {
printf("collective irregular contiguous read\n");
fflush(stdout);
}
coll_irregular_cont_read();
if (MAINPROCESS) {
printf("collective irregular simple chunk write\n");
fflush(stdout);
}
coll_irregular_simple_chunk_write();
if (MAINPROCESS) {
printf("collective irregular simple chunk read\n");
fflush(stdout);
}
coll_irregular_simple_chunk_read();
if (MAINPROCESS) {
printf("collective irregular complex chunk write\n");
fflush(stdout);
}
coll_irregular_complex_chunk_write();
if (MAINPROCESS) {
printf("collective irregular complex chunk read\n");
fflush(stdout);
}
coll_irregular_complex_chunk_read();
#if 0
AddTest("null", null_dataset, NULL,
"null dataset test", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("null dataset test\n");
fflush(stdout);
}
null_dataset();
#if 0
io_mode_confusion_params.name = PARATESTFILE;
io_mode_confusion_params.count = 0; /* value not used */
AddTest("I/Omodeconf", io_mode_confusion, NULL,
"I/O mode confusion test",
&io_mode_confusion_params);
#endif
if (MAINPROCESS) {
printf("I/O mode confusion test\n");
fflush(stdout);
}
io_mode_confusion();
if ((mpi_size < 3) && MAINPROCESS) {
HDprintf("rr_obj_hdr_flush_confusion test needs at least 3 processes.\n");
HDprintf("rr_obj_hdr_flush_confusion test will be skipped \n");
}
if (mpi_size > 2) {
#if 0
rr_obj_flush_confusion_params.name = PARATESTFILE;
rr_obj_flush_confusion_params.count = 0; /* value not used */
AddTest("rrobjflushconf", rr_obj_hdr_flush_confusion, NULL,
"round robin object header flush confusion test",
&rr_obj_flush_confusion_params);
#endif
if (MAINPROCESS) {
printf("round robin object header flush confusion test\n");
fflush(stdout);
}
rr_obj_hdr_flush_confusion();
}
#if 0
AddTest("alnbg1",
chunk_align_bug_1, NULL,
"Chunk allocation with alignment bug.",
PARATESTFILE);
AddTest("tldsc",
lower_dim_size_comp_test, NULL,
"test lower dim size comp in span tree to mpi derived type",
PARATESTFILE);
AddTest("lccio",
link_chunk_collective_io_test, NULL,
"test mpi derived type management",
PARATESTFILE);
AddTest("actualio", actual_io_mode_tests, NULL,
"test actual io mode proprerty",
PARATESTFILE);
AddTest("nocolcause", no_collective_cause_tests, NULL,
"test cause for broken collective io",
PARATESTFILE);
AddTest("edpl", test_plist_ed, NULL,
"encode/decode Property Lists", NULL);
#endif
if (MAINPROCESS) {
printf("Chunk allocation with alignment bug\n");
fflush(stdout);
}
chunk_align_bug_1();
if (MAINPROCESS) {
printf("test lower dim size comp in span tree to mpi derived type\n");
fflush(stdout);
}
lower_dim_size_comp_test();
if (MAINPROCESS) {
printf("test mpi derived type management\n");
fflush(stdout);
}
link_chunk_collective_io_test();
if (MAINPROCESS) {
printf("test actual io mode property - SKIPPED currently due to native-specific testing\n");
fflush(stdout);
}
/* actual_io_mode_tests(); */
if (MAINPROCESS) {
printf("test cause for broken collective io - SKIPPED currently due to native-specific testing\n");
fflush(stdout);
}
/* no_collective_cause_tests(); */
if (MAINPROCESS) {
printf("encode/decode Property Lists\n");
fflush(stdout);
}
test_plist_ed();
if ((mpi_size < 2) && MAINPROCESS) {
HDprintf("File Image Ops daisy chain test needs at least 2 processes.\n");
HDprintf("File Image Ops daisy chain test will be skipped \n");
}
#if 0
AddTest((mpi_size < 2)? "-fiodc" : "fiodc", file_image_daisy_chain_test, NULL,
"file image ops daisy chain", NULL);
#endif
if (mpi_size >= 2) {
if (MAINPROCESS) {
printf("file image ops daisy chain - SKIPPED currently due to native-specific testing\n");
fflush(stdout);
}
/* file_image_daisy_chain_test(); */
}
if ((mpi_size < 2) && MAINPROCESS) {
HDprintf("Atomicity tests need at least 2 processes to participate\n");
HDprintf("8 is more recommended.. Atomicity tests will be skipped \n");
}
else if (facc_type != FACC_MPIO && MAINPROCESS) {
HDprintf("Atomicity tests will not work with a non MPIO VFD\n");
}
else if (mpi_size >= 2 && facc_type == FACC_MPIO) {
#if 0
AddTest("atomicity", dataset_atomicity, NULL,
"dataset atomic updates", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("dataset atomic updates - SKIPPED currently due to native-specific testing\n");
fflush(stdout);
}
/* dataset_atomicity(); */
}
#if 0
AddTest("denseattr", test_dense_attr, NULL,
"Store Dense Attributes", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("Store Dense Attributes\n");
fflush(stdout);
}
test_dense_attr();
#if 0
AddTest("noselcollmdread", test_partial_no_selection_coll_md_read, NULL,
"Collective Metadata read with some ranks having no selection", PARATESTFILE);
AddTest("MC_coll_MD_read", test_multi_chunk_io_addrmap_issue, NULL,
"Collective MD read with multi chunk I/O (H5D__chunk_addrmap)", PARATESTFILE);
AddTest("LC_coll_MD_read", test_link_chunk_io_sort_chunk_issue, NULL,
"Collective MD read with link chunk I/O (H5D__sort_chunk)", PARATESTFILE);
#endif
if (MAINPROCESS) {
printf("Collective Metadata read with some ranks having no selection\n");
fflush(stdout);
}
test_partial_no_selection_coll_md_read();
if (MAINPROCESS) {
printf("Collective MD read with multi chunk I/O\n");
fflush(stdout);
}
test_multi_chunk_io_addrmap_issue();
if (MAINPROCESS) {
printf("Collective MD read with link chunk I/O\n");
fflush(stdout);
}
test_link_chunk_io_sort_chunk_issue();
/* Display testing information */
/* TestInfo(argv[0]); */
/* setup file access property list */
H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL);
/* Parse command line arguments */
/* TestParseCmdLine(argc, argv); */
if (dxfer_coll_type == DXFER_INDEPENDENT_IO && MAINPROCESS) {
HDprintf("===================================\n"
" Using Independent I/O with file set view to replace collective I/O \n"
"===================================\n");
}
/* Perform requested testing */
/* PerformTests(); */
/* make sure all processes are finished before final report, cleanup
* and exit.
*/
MPI_Barrier(MPI_COMM_WORLD);
/* Display test summary, if requested */
/* if (MAINPROCESS && GetTestSummary())
TestSummary(); */
/* Clean up test files */
/* h5_clean_files(FILENAME, fapl); */
H5Fdelete(FILENAME[0], fapl);
H5Pclose(fapl);
/* nerrors += GetTestNumErrs(); */
/* Gather errors from all processes */
{
int temp;
MPI_Allreduce(&nerrors, &temp, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
nerrors = temp;
}
if (MAINPROCESS) { /* only process 0 reports */
HDprintf("===================================\n");
if (nerrors)
HDprintf("***PHDF5 tests detected %d errors***\n", nerrors);
else
HDprintf("PHDF5 tests finished successfully\n");
HDprintf("===================================\n");
}
#if 0
for (int i = 0; i < NFILENAME; i++) {
HDfree(filenames[i]);
filenames[i] = NULL;
}
#endif
/* close HDF5 library */
H5close();
/* Release test infrastructure */
/* TestShutdown(); */
/* MPI_Finalize must be called AFTER H5close which may use MPI calls */
MPI_Finalize();
/* cannot just return (nerrors) because exit code is limited to 1byte */
return (nerrors != 0);
}
+343
View File
@@ -0,0 +1,343 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* common definitions used by all parallel hdf5 test programs. */
#ifndef PHDF5TEST_H
#define PHDF5TEST_H
#include "H5private.h"
#include "testpar.h"
#include "H5_api_tests_disabled.h"
/*
* Define parameters for various tests since we do not have access to
* passing parameters to tests via the testphdf5 test framework.
*/
#define PARATESTFILE "ParaTest.h5"
#define NDATASETS 300
#define NGROUPS 256
/* Disable express testing by default */
#define EXPRESS_MODE 0
enum H5TEST_COLL_CHUNK_API {
API_NONE = 0,
API_LINK_HARD,
API_MULTI_HARD,
API_LINK_TRUE,
API_LINK_FALSE,
API_MULTI_COLL,
API_MULTI_IND
};
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
/* Constants definitions */
#define DIM0 600 /* Default dataset sizes. */
#define DIM1 1200 /* Values are from a monitor pixel sizes */
#define ROW_FACTOR 8 /* Nominal row factor for dataset size */
#define COL_FACTOR 16 /* Nominal column factor for dataset size */
#define RANK 2
#define DATASETNAME1 "Data1"
#define DATASETNAME2 "Data2"
#define DATASETNAME3 "Data3"
#define DATASETNAME4 "Data4"
#define DATASETNAME5 "Data5"
#define DATASETNAME6 "Data6"
#define DATASETNAME7 "Data7"
#define DATASETNAME8 "Data8"
#define DATASETNAME9 "Data9"
/* point selection order */
#define IN_ORDER 1
#define OUT_OF_ORDER 2
/* Hyperslab layout styles */
#define BYROW 1 /* divide into slabs of rows */
#define BYCOL 2 /* divide into blocks of columns */
#define ZROW 3 /* same as BYCOL except process 0 gets 0 rows */
#define ZCOL 4 /* same as BYCOL except process 0 gets 0 columns */
/* File_Access_type bits */
#define FACC_DEFAULT 0x0 /* default */
#define FACC_MPIO 0x1 /* MPIO */
#define FACC_SPLIT 0x2 /* Split File */
#define DXFER_COLLECTIVE_IO 0x1 /* Collective IO*/
#define DXFER_INDEPENDENT_IO 0x2 /* Independent IO collectively */
/*Constants for collective chunk definitions */
#define SPACE_DIM1 24
#define SPACE_DIM2 4
#define BYROW_CONT 1
#define BYROW_DISCONT 2
#define BYROW_SELECTNONE 3
#define BYROW_SELECTUNBALANCE 4
#define BYROW_SELECTINCHUNK 5
#define DIMO_NUM_CHUNK 4
#define DIM1_NUM_CHUNK 2
#define LINK_TRUE_NUM_CHUNK 2
#define LINK_FALSE_NUM_CHUNK 6
#define MULTI_TRUE_PERCENT 50
#define LINK_TRUE_CHUNK_NAME "h5_link_chunk_true"
#define LINK_FALSE_CHUNK_NAME "h5_link_chunk_false"
#define LINK_HARD_CHUNK_NAME "h5_link_chunk_hard"
#define MULTI_HARD_CHUNK_NAME "h5_multi_chunk_hard"
#define MULTI_COLL_CHUNK_NAME "h5_multi_chunk_coll"
#define MULTI_INDP_CHUNK_NAME "h5_multi_chunk_indp"
#define DSET_COLLECTIVE_CHUNK_NAME "coll_chunk_name"
/*Constants for MPI derived data type generated from span tree */
#define MSPACE1_RANK 1 /* Rank of the first dataset in memory */
#define MSPACE1_DIM 27000 /* Dataset size in memory */
#define FSPACE_RANK 2 /* Dataset rank as it is stored in the file */
#define FSPACE_DIM1 9 /* Dimension sizes of the dataset as it is stored in the file */
#define FSPACE_DIM2 3600
/* We will read dataset back from the file to the dataset in memory with these dataspace parameters. */
#define MSPACE_RANK 2
#define MSPACE_DIM1 9
#define MSPACE_DIM2 3600
#define FHCOUNT0 1 /* Count of the first dimension of the first hyperslab selection*/
#define FHCOUNT1 768 /* Count of the second dimension of the first hyperslab selection*/
#define FHSTRIDE0 4 /* Stride of the first dimension of the first hyperslab selection*/
#define FHSTRIDE1 3 /* Stride of the second dimension of the first hyperslab selection*/
#define FHBLOCK0 3 /* Block of the first dimension of the first hyperslab selection*/
#define FHBLOCK1 2 /* Block of the second dimension of the first hyperslab selection*/
#define FHSTART0 0 /* start of the first dimension of the first hyperslab selection*/
#define FHSTART1 1 /* start of the second dimension of the first hyperslab selection*/
#define SHCOUNT0 1 /* Count of the first dimension of the first hyperslab selection*/
#define SHCOUNT1 1 /* Count of the second dimension of the first hyperslab selection*/
#define SHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define SHSTRIDE1 1 /* Stride of the second dimension of the first hyperslab selection*/
#define SHBLOCK0 3 /* Block of the first dimension of the first hyperslab selection*/
#define SHBLOCK1 768 /* Block of the second dimension of the first hyperslab selection*/
#define SHSTART0 4 /* start of the first dimension of the first hyperslab selection*/
#define SHSTART1 0 /* start of the second dimension of the first hyperslab selection*/
#define MHCOUNT0 6912 /* Count of the first dimension of the first hyperslab selection*/
#define MHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define MHBLOCK0 1 /* Block of the first dimension of the first hyperslab selection*/
#define MHSTART0 1 /* start of the first dimension of the first hyperslab selection*/
#define RFFHCOUNT0 3 /* Count of the first dimension of the first hyperslab selection*/
#define RFFHCOUNT1 768 /* Count of the second dimension of the first hyperslab selection*/
#define RFFHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define RFFHSTRIDE1 1 /* Stride of the second dimension of the first hyperslab selection*/
#define RFFHBLOCK0 1 /* Block of the first dimension of the first hyperslab selection*/
#define RFFHBLOCK1 1 /* Block of the second dimension of the first hyperslab selection*/
#define RFFHSTART0 1 /* start of the first dimension of the first hyperslab selection*/
#define RFFHSTART1 2 /* start of the second dimension of the first hyperslab selection*/
#define RFSHCOUNT0 3 /* Count of the first dimension of the first hyperslab selection*/
#define RFSHCOUNT1 1536 /* Count of the second dimension of the first hyperslab selection*/
#define RFSHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define RFSHSTRIDE1 1 /* Stride of the second dimension of the first hyperslab selection*/
#define RFSHBLOCK0 1 /* Block of the first dimension of the first hyperslab selection*/
#define RFSHBLOCK1 1 /* Block of the second dimension of the first hyperslab selection*/
#define RFSHSTART0 2 /* start of the first dimension of the first hyperslab selection*/
#define RFSHSTART1 4 /* start of the second dimension of the first hyperslab selection*/
#define RMFHCOUNT0 3 /* Count of the first dimension of the first hyperslab selection*/
#define RMFHCOUNT1 768 /* Count of the second dimension of the first hyperslab selection*/
#define RMFHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define RMFHSTRIDE1 1 /* Stride of the second dimension of the first hyperslab selection*/
#define RMFHBLOCK0 1 /* Block of the first dimension of the first hyperslab selection*/
#define RMFHBLOCK1 1 /* Block of the second dimension of the first hyperslab selection*/
#define RMFHSTART0 0 /* start of the first dimension of the first hyperslab selection*/
#define RMFHSTART1 0 /* start of the second dimension of the first hyperslab selection*/
#define RMSHCOUNT0 3 /* Count of the first dimension of the first hyperslab selection*/
#define RMSHCOUNT1 1536 /* Count of the second dimension of the first hyperslab selection*/
#define RMSHSTRIDE0 1 /* Stride of the first dimension of the first hyperslab selection*/
#define RMSHSTRIDE1 1 /* Stride of the second dimension of the first hyperslab selection*/
#define RMSHBLOCK0 1 /* Block of the first dimension of the first hyperslab selection*/
#define RMSHBLOCK1 1 /* Block of the second dimension of the first hyperslab selection*/
#define RMSHSTART0 1 /* start of the first dimension of the first hyperslab selection*/
#define RMSHSTART1 2 /* start of the second dimension of the first hyperslab selection*/
#define NPOINTS \
4 /* Number of points that will be selected \
and overwritten */
/* Definitions of the selection mode for the test_actual_io_function. */
#define TEST_ACTUAL_IO_NO_COLLECTIVE 0
#define TEST_ACTUAL_IO_RESET 1
#define TEST_ACTUAL_IO_MULTI_CHUNK_IND 2
#define TEST_ACTUAL_IO_MULTI_CHUNK_COL 3
#define TEST_ACTUAL_IO_MULTI_CHUNK_MIX 4
#define TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE 5
#define TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND 6
#define TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL 7
#define TEST_ACTUAL_IO_LINK_CHUNK 8
#define TEST_ACTUAL_IO_CONTIGUOUS 9
/* Definitions of the selection mode for the no_collective_cause_tests function. */
#define TEST_COLLECTIVE 0x001
#define TEST_SET_INDEPENDENT 0x002
#define TEST_DATATYPE_CONVERSION 0x004
#define TEST_DATA_TRANSFORMS 0x008
#define TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES 0x010
#define TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT 0x020
#define TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL 0x040
/* Don't erase these lines, they are put here for debugging purposes */
/*
#define MSPACE1_RANK 1
#define MSPACE1_DIM 50
#define MSPACE2_RANK 1
#define MSPACE2_DIM 4
#define FSPACE_RANK 2
#define FSPACE_DIM1 8
#define FSPACE_DIM2 12
#define MSPACE_RANK 2
#define MSPACE_DIM1 8
#define MSPACE_DIM2 9
#define NPOINTS 4
*/ /* end of debugging macro */
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
/* Collective chunk instrumentation properties */
#define H5D_XFER_COLL_CHUNK_LINK_HARD_NAME "coll_chunk_link_hard"
#define H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME "coll_chunk_multi_hard"
#define H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME "coll_chunk_link_true"
#define H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME "coll_chunk_link_false"
#define H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME "coll_chunk_multi_coll"
#define H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME "coll_chunk_multi_ind"
/* Definitions for all collective chunk instrumentation properties */
#define H5D_XFER_COLL_CHUNK_SIZE sizeof(unsigned)
#define H5D_XFER_COLL_CHUNK_DEF 1
/* General collective I/O instrumentation properties */
#define H5D_XFER_COLL_RANK0_BCAST_NAME "coll_rank0_bcast"
/* Definitions for general collective I/O instrumentation properties */
#define H5D_XFER_COLL_RANK0_BCAST_SIZE sizeof(hbool_t)
#define H5D_XFER_COLL_RANK0_BCAST_DEF FALSE
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
/* type definitions */
typedef struct H5Ptest_param_t /* holds extra test parameters */
{
char *name;
int count;
} H5Ptest_param_t;
/* Dataset data type. Int's can be easily octo dumped. */
typedef int DATATYPE;
/* Shape Same Tests Definitions */
typedef enum {
IND_CONTIG, /* Independent IO on contiguous datasets */
COL_CONTIG, /* Collective IO on contiguous datasets */
IND_CHUNKED, /* Independent IO on chunked datasets */
COL_CHUNKED /* Collective IO on chunked datasets */
} ShapeSameTestMethods;
/* Shared global variables */
extern int dim0, dim1; /*Dataset dimensions */
extern int chunkdim0, chunkdim1; /*Chunk dimensions */
extern int nerrors; /*errors count */
extern H5E_auto2_t old_func; /* previous error handler */
extern void *old_client_data; /*previous error handler arg.*/
extern int facc_type; /*Test file access type */
extern int dxfer_coll_type;
/* Test program prototypes */
void test_plist_ed(void);
#if 0
void external_links(void);
#endif
void zero_dim_dset(void);
void test_file_properties(void);
void test_delete(void);
void multiple_dset_write(void);
void multiple_group_write(void);
void multiple_group_read(void);
void collective_group_write_independent_group_read(void);
void collective_group_write(void);
void independent_group_read(void);
void test_fapl_mpio_dup(void);
void test_split_comm_access(void);
void test_page_buffer_access(void);
void dataset_atomicity(void);
void dataset_writeInd(void);
void dataset_writeAll(void);
void extend_writeInd(void);
void extend_writeInd2(void);
void extend_writeAll(void);
void dataset_readInd(void);
void dataset_readAll(void);
void extend_readInd(void);
void extend_readAll(void);
void none_selection_chunk(void);
void actual_io_mode_tests(void);
void no_collective_cause_tests(void);
void test_chunk_alloc(void);
void test_filter_read(void);
void compact_dataset(void);
void null_dataset(void);
void big_dataset(void);
void dataset_fillvalue(void);
void coll_chunk1(void);
void coll_chunk2(void);
void coll_chunk3(void);
void coll_chunk4(void);
void coll_chunk5(void);
void coll_chunk6(void);
void coll_chunk7(void);
void coll_chunk8(void);
void coll_chunk9(void);
void coll_chunk10(void);
void coll_irregular_cont_read(void);
void coll_irregular_cont_write(void);
void coll_irregular_simple_chunk_read(void);
void coll_irregular_simple_chunk_write(void);
void coll_irregular_complex_chunk_read(void);
void coll_irregular_complex_chunk_write(void);
void io_mode_confusion(void);
void rr_obj_hdr_flush_confusion(void);
void rr_obj_hdr_flush_confusion_reader(MPI_Comm comm);
void rr_obj_hdr_flush_confusion_writer(MPI_Comm comm);
void chunk_align_bug_1(void);
void lower_dim_size_comp_test(void);
void link_chunk_collective_io_test(void);
void contig_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
void checker_board_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
void file_image_daisy_chain_test(void);
#ifdef H5_HAVE_FILTER_DEFLATE
void compress_readAll(void);
#endif /* H5_HAVE_FILTER_DEFLATE */
void test_dense_attr(void);
void test_partial_no_selection_coll_md_read(void);
void test_multi_chunk_io_addrmap_issue(void);
void test_link_chunk_io_sort_chunk_issue(void);
void test_collective_global_heap_write(void);
/* commonly used prototypes */
hid_t create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type);
MPI_Offset h5_mpi_get_file_size(const char *filename, MPI_Comm comm, MPI_Info info);
int dataset_vrfy(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], DATATYPE *dataset,
DATATYPE *original);
void point_set(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], size_t num_points,
hsize_t coords[], int order);
#endif /* PHDF5TEST_H */