summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Kim <jkm@hdfgroup.org>2012-09-17 19:14:56 (GMT)
committerJonathan Kim <jkm@hdfgroup.org>2012-09-17 19:14:56 (GMT)
commit5188e7a61773c8a72a8f228d8dc4c68eaef9b7d4 (patch)
tree36d011890c577906a5af40c51ce7dbdca72e7feb
parentb22ef5f8a78f078d6dff70a1eabc242503f3c848 (diff)
downloadhdf5-5188e7a61773c8a72a8f228d8dc4c68eaef9b7d4.zip
hdf5-5188e7a61773c8a72a8f228d8dc4c68eaef9b7d4.tar.gz
hdf5-5188e7a61773c8a72a8f228d8dc4c68eaef9b7d4.tar.bz2
[svn-r22780] Purpose:
HDFFV-8143 Provide a routine(s) for telling the user why the library broke collective data access Description: Added H5Pget_mpio_no_collective_cause() function that retrive reasons why the collective I/O was broken during Read/Write IO access. Reasons to break collective I/O: - SET_INDEPENDENT - DATATYPE_CONVERSION - DATA_TRANSFORMS - MPIPOSIX - NOT_SIMPLE_OR_SCALAR_DATASPACES (NULL Space) - POINT_SELECTIONS - NOT_CONTIGUOUS_OR_CHUNKED_DATASET (Compact or External-Storage) - FILTERS Merged from HDF5 trunk r22735, r22741 , 22743, 22744, 22763. Tested: jam-pp (linux32-LE), koala-pp (linux64-LE), wallaby-pp
-rwxr-xr-xbin/trace1
-rw-r--r--release_docs/RELEASE.txt4
-rw-r--r--src/H5Dio.c2
-rw-r--r--src/H5Dmpio.c66
-rw-r--r--src/H5Dpkg.h3
-rw-r--r--src/H5Dprivate.h2
-rw-r--r--src/H5Pdxpl.c51
-rw-r--r--src/H5Ppublic.h14
-rw-r--r--src/H5trace.c54
-rw-r--r--testpar/t_dset.c676
-rw-r--r--testpar/testphdf5.c4
-rw-r--r--testpar/testphdf5.h16
12 files changed, 863 insertions, 30 deletions
diff --git a/bin/trace b/bin/trace
index 188b858..3e82f43 100755
--- a/bin/trace
+++ b/bin/trace
@@ -38,6 +38,7 @@ $Source = "";
"H5FD_mpio_chunk_opt_t" => "Dh",
"H5D_mpio_actual_io_mode_t" => "Di",
"H5D_layout_t" => "Dl",
+ "H5D_mpio_no_collective_cause_t" => "Dn",
"H5D_mpio_actual_chunk_opt_mode_t" => "Do",
"H5D_space_status_t" => "Ds",
"H5FD_mpio_xfer_t" => "Dt",
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 7c55677..2f6e2c0 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -72,7 +72,9 @@ New Features
Parallel Library
----------------
- - None
+ - Add H5Pget_mpio_no_collective_cause() function that retrive reasons
+ why the collective I/O was broken during read/write IO access.
+ (JKM - 2012/08/30 HDFFV-8143)
Tools
-----
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 917fd89..0493a9e 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -996,7 +996,7 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, hid_t dxpl_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator")
/* Check if we can set direct MPI-IO read/write functions */
- if((opt = H5D__mpio_opt_possible(io_info, file_space, mem_space, type_info, fm)) < 0)
+ if((opt = H5D__mpio_opt_possible(io_info, file_space, mem_space, type_info, fm, dx_plist)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid check for direct IO dataspace ")
/* Check if we can use the optimized parallel I/O routines */
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index 9b8fa27..c2d964e 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -156,10 +156,12 @@ static herr_t H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info,
htri_t
H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space,
const H5S_t *mem_space, const H5D_type_info_t *type_info,
- const H5D_chunk_map_t *fm)
+ const H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist)
{
- int local_opinion = TRUE; /* This process's idea of whether to perform collective I/O or not */
- int consensus; /* Consensus opinion of all processes */
+ /* variables to set cause of broken collective I/O */
+ int local_cause = 0;
+ int global_cause = 0;
+
int mpi_code; /* MPI error code */
htri_t ret_value = TRUE;
@@ -171,51 +173,54 @@ H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space,
HDassert(file_space);
HDassert(type_info);
+
/* For independent I/O, get out quickly and don't try to form consensus */
- if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT)
+ if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT) {
+ local_cause = H5D_MPIO_SET_INDEPENDENT;
+ global_cause = H5D_MPIO_SET_INDEPENDENT;
HGOTO_DONE(FALSE);
+ }
+
+ /* Optimized MPI types flag must be set and it must be collective IO */
+ /* (Don't allow parallel I/O for the MPI-posix driver, since it doesn't do real collective I/O) */
+ if(!(H5S_mpi_opt_types_g && io_info->dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE
+ && !IS_H5FD_MPIPOSIX(io_info->dset->oloc.file))) {
+ local_cause |= H5D_MPIO_SET_MPIPOSIX;
+ } /* end if */
/* Don't allow collective operations if datatype conversions need to happen */
if(!type_info->is_conv_noop) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_DATATYPE_CONVERSION;
} /* end if */
/* Don't allow collective operations if data transform operations should occur */
if(!type_info->is_xform_noop) {
- local_opinion = FALSE;
- goto broadcast;
- } /* end if */
-
- /* Optimized MPI types flag must be set and it must be collective IO */
- /* (Don't allow parallel I/O for the MPI-posix driver, since it doesn't do real collective I/O) */
- if(!(H5S_mpi_opt_types_g && io_info->dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE
- && !IS_H5FD_MPIPOSIX(io_info->dset->oloc.file))) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_DATA_TRANSFORMS;
} /* end if */
/* Check whether these are both simple or scalar dataspaces */
if(!((H5S_SIMPLE == H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(mem_space))
&& (H5S_SIMPLE == H5S_GET_EXTENT_TYPE(file_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(file_space)))) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES;
} /* end if */
/* Can't currently handle point selections */
if(H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(mem_space)
|| H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(file_space)) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_POINT_SELECTIONS;
} /* end if */
/* Dataset storage must be contiguous or chunked */
if(!(io_info->dset->shared->layout.type == H5D_CONTIGUOUS ||
io_info->dset->shared->layout.type == H5D_CHUNKED)) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
} /* end if */
+ /* check if external-file storage is used */
+ if (io_info->dset->shared->dcpl_cache.efl.nused > 0) {
+ local_cause |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
+ }
+
/* The handling of memory space is different for chunking and contiguous
* storage. For contiguous storage, mem_space and file_space won't change
* when it it is doing disk IO. For chunking storage, mem_space will
@@ -226,21 +231,28 @@ H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space,
/* Don't allow collective operations if filters need to be applied */
if(io_info->dset->shared->layout.type == H5D_CHUNKED) {
if(io_info->dset->shared->dcpl_cache.pline.nused > 0) {
- local_opinion = FALSE;
- goto broadcast;
+ local_cause |= H5D_MPIO_FILTERS;
} /* end if */
} /* end if */
-broadcast:
/* Form consensus opinion among all processes about whether to perform
* collective I/O
*/
- if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_opinion, &consensus, 1, MPI_INT, MPI_LAND, io_info->comm)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, MPI_INT, MPI_BOR, io_info->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code)
- ret_value = consensus > 0 ? TRUE : FALSE;
+ ret_value = global_cause > 0 ? FALSE : TRUE;
+
done:
+ /* Write the local value of no-collective-cause to the DXPL. */
+ if(H5P_set(dx_plist, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME, &local_cause) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set local no collective cause property")
+
+ /* Write the global value of no-collective-cause to the DXPL. */
+ if(H5P_set(dx_plist, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, &global_cause) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set global no collective cause property")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D__mpio_opt_possible() */
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index dfc19b8..ed6da8f 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -693,7 +693,8 @@ H5_DLL herr_t H5D__chunk_collective_write(H5D_io_info_t *io_info,
* memory and the file */
H5_DLL htri_t H5D__mpio_opt_possible(const H5D_io_info_t *io_info,
const H5S_t *file_space, const H5S_t *mem_space,
- const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm);
+ const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm,
+ H5P_genplist_t *dx_plist);
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 2211f79..85051c3 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -74,6 +74,8 @@
#define H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME "mpio_chunk_opt_ratio"
#define H5D_MPIO_ACTUAL_CHUNK_OPT_MODE_NAME "actual_chunk_opt_mode"
#define H5D_MPIO_ACTUAL_IO_MODE_NAME "actual_io_mode"
+#define H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME "local_no_collective_cause" /* cause of broken collective I/O in each process */
+#define H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME "global_no_collective_cause" /* cause of broken collective I/O in all processes */
#endif /* H5_HAVE_PARALLEL */
#define H5D_XFER_EDC_NAME "err_detect" /* EDC */
#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 87e6c89..4c98dd6 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -101,6 +101,9 @@
/* Definitions for chunk io mode property. */
#define H5D_MPIO_ACTUAL_IO_MODE_SIZE sizeof(H5D_mpio_actual_io_mode_t)
#define H5D_MPIO_ACTUAL_IO_MODE_DEF H5D_MPIO_NO_COLLECTIVE
+/* Definitions for cause of broken collective io property */
+#define H5D_MPIO_NO_COLLECTIVE_CAUSE_SIZE sizeof(uint32_t)
+#define H5D_MPIO_NO_COLLECTIVE_CAUSE_DEF H5D_MPIO_COLLECTIVE
/* Definitions for memory MPI type property */
#define H5FD_MPI_XFER_MEM_MPI_TYPE_SIZE sizeof(MPI_Datatype)
#define H5FD_MPI_XFER_MEM_MPI_TYPE_DEF MPI_DATATYPE_NULL
@@ -209,6 +212,7 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
unsigned def_mpio_chunk_opt_ratio = H5D_XFER_MPIO_CHUNK_OPT_RATIO_DEF;
H5D_mpio_actual_chunk_opt_mode_t def_mpio_actual_chunk_opt_mode = H5D_MPIO_ACTUAL_CHUNK_OPT_MODE_DEF;
H5D_mpio_actual_io_mode_t def_mpio_actual_io_mode = H5D_MPIO_ACTUAL_IO_MODE_DEF;
+ H5D_mpio_no_collective_cause_t def_mpio_no_collective_cause = H5D_MPIO_NO_COLLECTIVE_CAUSE_DEF;
MPI_Datatype btype = H5FD_MPI_XFER_MEM_MPI_TYPE_DEF; /* Default value for MPI buffer type */
MPI_Datatype ftype = H5FD_MPI_XFER_FILE_MPI_TYPE_DEF; /* Default value for MPI file type */
#endif /* H5_HAVE_PARALLEL */
@@ -281,6 +285,14 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
if(H5P_register_real(pclass, H5D_MPIO_ACTUAL_IO_MODE_NAME, H5D_MPIO_ACTUAL_IO_MODE_SIZE, &def_mpio_actual_io_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the local cause of broken collective I/O */
+ if(H5P_register_real(pclass, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME, H5D_MPIO_NO_COLLECTIVE_CAUSE_SIZE, &def_mpio_no_collective_cause, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the global cause of broken collective I/O */
+ if(H5P_register_real(pclass, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, H5D_MPIO_NO_COLLECTIVE_CAUSE_SIZE, &def_mpio_no_collective_cause, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
/* Register the MPI memory type property */
if(H5P_register_real(pclass, H5FD_MPI_XFER_MEM_MPI_TYPE_NAME, H5FD_MPI_XFER_MEM_MPI_TYPE_SIZE,
&btype, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
@@ -1354,5 +1366,44 @@ H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode_t *actual_io_
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_mpio_actual_io_mode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_mpio_no_collective_cause
+ *
+ * Purpose: Retrieves cause for the broke collective I/O
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jonathan Kim
+ * Aug 3, 2012
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause)
+{
+ H5P_genplist_t *plist;
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*Dn*Dn", plist_id, local_no_collective_cause,
+ global_no_collective_cause);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Return values */
+ if(local_no_collective_cause)
+ if(H5P_get(plist, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME, local_no_collective_cause) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get local value")
+ if(global_no_collective_cause)
+ if(H5P_get(plist, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, global_no_collective_cause) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get global value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_mpio_no_collective_cause() */
+
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index c06ab39..8681f65 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -153,6 +153,19 @@ typedef enum H5D_mpio_actual_io_mode_t {
H5D_MPIO_CONTIGUOUS_COLLECTIVE = 0x4
} H5D_mpio_actual_io_mode_t;
+/* Broken collective IO property */
+typedef enum H5D_mpio_no_collective_cause_t {
+ H5D_MPIO_COLLECTIVE = 0x00,
+ H5D_MPIO_SET_INDEPENDENT = 0x01,
+ H5D_MPIO_DATATYPE_CONVERSION = 0x02,
+ H5D_MPIO_DATA_TRANSFORMS = 0x04,
+ H5D_MPIO_SET_MPIPOSIX = 0x08,
+ H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES = 0x10,
+ H5D_MPIO_POINT_SELECTIONS = 0x20,
+ H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET = 0x40,
+ H5D_MPIO_FILTERS = 0x80
+} H5D_mpio_no_collective_cause_t;
+
/********************/
/* Public Variables */
/********************/
@@ -400,6 +413,7 @@ H5_DLL herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, voi
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5Pget_mpio_actual_chunk_opt_mode(hid_t plist_id, H5D_mpio_actual_chunk_opt_mode_t *actual_chunk_opt_mode);
H5_DLL herr_t H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode_t *actual_io_mode);
+H5_DLL herr_t H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause);
#endif /* H5_HAVE_PARALLEL */
/* Link creation property list (LCPL) routines */
diff --git a/src/H5trace.c b/src/H5trace.c
index e0b5794..9d0fd5b 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -535,6 +535,60 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end else */
break;
+ case 'n':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5D_mpio_no_collective_cause_t nocol_cause_mode = (H5D_mpio_no_collective_cause_t)va_arg(ap, int);
+
+ switch(nocol_cause_mode) {
+ case H5D_MPIO_COLLECTIVE:
+ fprintf(out, "H5D_MPIO_COLLECTIVE");
+ break;
+
+ case H5D_MPIO_SET_INDEPENDENT:
+ fprintf(out, "H5D_MPIO_SET_INDEPENDENT");
+ break;
+
+ case H5D_MPIO_DATATYPE_CONVERSION:
+ fprintf(out, "H5D_MPIO_DATATYPE_CONVERSION");
+ break;
+
+ case H5D_MPIO_DATA_TRANSFORMS:
+ fprintf(out, "H5D_MPIO_DATA_TRANSFORMS");
+ break;
+
+ case H5D_MPIO_SET_MPIPOSIX:
+ fprintf(out, "H5D_MPIO_SET_MPIPOSIX");
+ break;
+
+ case H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES:
+ fprintf(out, "H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES");
+ break;
+
+ case H5D_MPIO_POINT_SELECTIONS:
+ fprintf(out, "H5D_MPIO_POINT_SELECTIONS");
+ break;
+
+ case H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET:
+ fprintf(out, "H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET");
+ break;
+
+ case H5D_MPIO_FILTERS:
+ fprintf(out, "H5D_MPIO_FILTERS");
+ break;
+
+ default:
+ fprintf(out, "%ld", (long)nocol_cause_mode);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
case 'o':
if(ptr) {
if(vp)
diff --git a/testpar/t_dset.c b/testpar/t_dset.c
index 84d69b0..22eefbc 100644
--- a/testpar/t_dset.c
+++ b/testpar/t_dset.c
@@ -3048,6 +3048,682 @@ actual_io_mode_tests(void) {
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 Transfrom feature as the cause of breaking collective I/O.
+ *
+ * TEST_SET_MPIPOSIX:
+ * Test for MPI Posix 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_POINT_SELECTIONS:
+ * Test for selecting elements of dataspce 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.
+ *
+ * TEST_FILTERS:
+ * Test for using filter (checksum) as the cause of breaking collective I/O.
+ * Note: TEST_FILTERS mode will not work until H5Dcreate and H5write is supported for mpio and filter feature. Use test_no_collective_cause_mode_filter() function instead.
+ *
+ *
+ * Programmer: Jonathan Kim
+ * Date: Aug, 2012
+ */
+#define DSET_NOCOLCAUSE "nocolcause"
+#define NELM 2
+#define FILE_EXTERNAL "nocolcause_extern.data"
+#undef H5_HAVE_FILTER_FLETCHER32
+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;
+ hsize_t coord[NELM][RANK];
+
+ 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_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 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];
+ hbool_t use_gpfs = FALSE;
+ herr_t ret;
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ H5Z_filter_t filter_info;
+#endif
+ /* 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_SET_MPIPOSIX) {
+ l_facc_type = FACC_MPIPOSIX;
+ }
+ else {
+ 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;
+ }
+
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ if (selection_mode & TEST_FILTERS) {
+ ret = H5Zfilter_avail(H5Z_FILTER_FLETCHER32);
+ VRFY ((ret >=0 ), "Fletcher32 filter is available.\n");
+
+ ret = H5Zget_filter_info (H5Z_FILTER_FLETCHER32, &filter_info);
+ VRFY ( ( (filter_info & H5Z_FILTER_CONFIG_ENCODE_ENABLED) || (filter_info & H5Z_FILTER_CONFIG_DECODE_ENABLED) ) , "Fletcher32 filter encoding and decoding available.\n");
+
+ ret = H5Pset_fletcher32(dcpl);
+ VRFY((ret >= 0),"set filter (flecher32) succeeded");
+ }
+#endif /* H5_HAVE_FILTER_FLETCHER32 */
+ }
+
+ 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 */
+ dims[0] = dim0;
+ dims[1] = dim1;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ }
+
+
+ filename = (const char *)GetTestParameters();
+ HDassert(filename != NULL);
+
+ /* Setup the file access template */
+ fapl = create_faccess_plist(mpi_comm, mpi_info, l_facc_type, use_gpfs);
+ 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]/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 Transfroms";
+ 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_POINT_SELECTIONS ) {
+ test_name = "Broken Collective I/O - Point Selection";
+ no_collective_cause_local_expected |= H5D_MPIO_POINT_SELECTIONS;
+ no_collective_cause_global_expected |= H5D_MPIO_POINT_SELECTIONS;
+ }
+
+ 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;
+ }
+
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ if (selection_mode & TEST_FILTERS) {
+ test_name = "Broken Collective I/O - Filter is required";
+ no_collective_cause_local_expected |= H5D_MPIO_FILTERS;
+ no_collective_cause_global_expected |= H5D_MPIO_FILTERS;
+ }
+#endif /* H5_HAVE_FILTER_FLETCHER32 */
+
+ if (selection_mode & TEST_SET_MPIPOSIX) {
+ test_name = "Broken Collective I/O - MPIO POSIX";
+ no_collective_cause_local_expected |= H5D_MPIO_SET_MPIPOSIX;
+ no_collective_cause_global_expected |= H5D_MPIO_SET_MPIPOSIX;
+ }
+
+ 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;
+ }
+
+ /* Add MPIPOSIX cause to expected cause if MPI_POSIX driver is in use '-p'.
+ * Exception to the independent cause.*/
+ if (facc_type == FACC_MPIPOSIX && !(selection_mode & TEST_SET_INDEPENDENT)) {
+ no_collective_cause_local_expected |= H5D_MPIO_SET_MPIPOSIX;
+ no_collective_cause_global_expected |= H5D_MPIO_SET_MPIPOSIX;
+ }
+
+ /* 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");
+ }
+
+ if (selection_mode & TEST_POINT_SELECTIONS) {
+ coord[0][0] = 0; coord[0][1] = 0;
+ coord[1][0] = 1; coord[1][1] = 1;
+ ret = H5Sselect_elements (file_space, H5S_SELECT_SET, NELM, (const hsize_t *)coord);
+ VRFY((ret >= 0), "H5Sselect_elements succeeded");
+
+ ret = H5Sselect_elements (mem_space, H5S_SELECT_SET, NELM, (const hsize_t *)coord);
+ VRFY((ret >= 0), "H5Sselect_elements succeeded");
+ }
+
+
+ /* Get the number of elements in the selection */
+ length = dim0 * dim1;
+
+ /* Allocate and initialize the buffer */
+ buffer = (int *)HDmalloc(sizeof(int) * length);
+ VRFY((buffer != NULL), "malloc 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), "retriving 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), "retriving 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 */
+ memset (message, 0, sizeof (message));
+ sprintf(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);
+ memset (message, 0, sizeof (message));
+ sprintf(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 (fapl)
+ H5Pclose(fapl);
+ 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)
+ HDremove(FILE_EXTERNAL);
+
+ return;
+}
+
+
+/*
+ * Function: test_no_collective_cause_mode_filter
+ *
+ * Purpose:
+ * Test specific for using filter as a caus of broken collective I/O and
+ * checks that the H5Pget_mpio_no_collective_cause properties in the DXPL
+ * have the correct values.
+ *
+ * NOTE:
+ * This is a temprary function.
+ * test_no_collective_cause_mode(TEST_FILTERS) will replace this when
+ * H5Dcreate and H5write support for mpio and filter feature.
+ *
+ * Input:
+ * TEST_FILTERS_READ:
+ * Test for using filter (checksum) as the cause of breaking collective I/O.
+ *
+ * Programmer: Jonathan Kim
+ * Date: Aug, 2012
+ */
+static void
+test_no_collective_cause_mode_filter(int selection_mode)
+{
+ uint32_t no_collective_cause_local_read = 0;
+ uint32_t no_collective_cause_local_expected = 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;
+ 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_write = -1;
+ hid_t fapl_read = -1;
+ hid_t dcpl = -1;
+ hid_t dxpl = -1;
+ hsize_t dims[RANK];
+ hid_t mem_space = -1;
+ hid_t file_space = -1;
+ hsize_t chunk_dims[RANK];
+ hbool_t use_gpfs = FALSE;
+ herr_t ret;
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ H5Z_filter_t filter_info;
+#endif
+ 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_FILTERS_READ ) {
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ ret = H5Zfilter_avail(H5Z_FILTER_FLETCHER32);
+ VRFY ((ret >=0 ), "Fletcher32 filter is available.\n");
+
+ ret = H5Zget_filter_info (H5Z_FILTER_FLETCHER32, (unsigned int *) &filter_info);
+ VRFY ( ( (filter_info & H5Z_FILTER_CONFIG_ENCODE_ENABLED) || (filter_info & H5Z_FILTER_CONFIG_DECODE_ENABLED) ) , "Fletcher32 filter encoding and decoding available.\n");
+
+ ret = H5Pset_fletcher32(dcpl);
+ VRFY((ret >= 0),"set filter (flecher32) succeeded");
+#endif /* H5_HAVE_FILTER_FLETCHER32 */
+ }
+ else {
+ VRFY(0, "Unexpected mode, only test for TEST_FILTERS_READ.");
+ }
+
+ /* Create the basic Space */
+ dims[0] = dim0;
+ dims[1] = dim1;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+
+
+ filename = (const char *)GetTestParameters();
+ HDassert(filename != NULL);
+
+ /* Setup the file access template */
+ fapl_write = create_faccess_plist(mpi_comm, mpi_info, FACC_DEFAULT, use_gpfs);
+ VRFY((fapl_write >= 0), "create_faccess_plist() succeeded");
+
+ fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_write);
+ VRFY((fid >= 0), "H5Fcreate succeeded");
+
+ /* If we are not testing contiguous datasets */
+ if(is_chunked) {
+ /* Set up chunk information. */
+ chunk_dims[0] = dims[0]/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, DSET_NOCOLCAUSE, data_type, sid, H5P_DEFAULT,
+ dcpl, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2() dataset succeeded");
+
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ /* Set expected cause */
+ test_name = "Broken Collective I/O - Filter is required";
+ no_collective_cause_local_expected = H5D_MPIO_FILTERS;
+ no_collective_cause_global_expected = H5D_MPIO_FILTERS;
+#endif
+
+ /* Ignore above expected cause and reset cause to MPIPOSIX if
+ * the MPI_POSIX driver is in use.*/
+ if (facc_type == FACC_MPIPOSIX) {
+ no_collective_cause_local_expected = H5D_MPIO_SET_MPIPOSIX;
+ no_collective_cause_global_expected = H5D_MPIO_SET_MPIPOSIX;
+ }
+
+ /* 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 = dim0 * dim1;
+
+ /* Allocate and initialize the buffer */
+ buffer = (int *)HDmalloc(sizeof(int) * length);
+ VRFY((buffer != NULL), "malloc of buffer succeeded");
+ for(i = 0; i < length; i++)
+ buffer[i] = i;
+
+ /* Set up the dxpl for the write */
+ dxpl = H5Pcreate(H5P_DATASET_XFER);
+ VRFY((dxpl >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
+
+ if (selection_mode == TEST_FILTERS_READ) {
+ /* To test read in collective I/O mode , write in independent mode
+ * because write fails with mpio + filter */
+ ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_INDEPENDENT);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ }
+ else {
+ /* To test write in collective I/O mode. */
+ ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ }
+
+
+ /* Write */
+ ret = H5Dwrite(dataset, data_type, mem_space, file_space, dxpl, buffer);
+
+ if(ret < 0) H5Eprint2(H5E_DEFAULT, stdout);
+ VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded");
+
+
+ /* Make a copy of the dxpl to test the read operation */
+ dxpl = H5Pcopy(dxpl);
+ VRFY((dxpl >= 0), "H5Pcopy succeeded");
+
+ if (dataset)
+ H5Dclose(dataset);
+ if (fapl_write)
+ H5Pclose(fapl_write);
+ if (fid)
+ H5Fclose(fid);
+
+
+ /*---------------------
+ * Test Read access
+ *---------------------*/
+
+ /* Setup the file access template */
+ fapl_read = create_faccess_plist(mpi_comm, mpi_info, facc_type, use_gpfs);
+ VRFY((fapl_read >= 0), "create_faccess_plist() succeeded");
+
+ fid = H5Fopen (filename, H5F_ACC_RDONLY, fapl_read);
+ dataset = H5Dopen (fid, DSET_NOCOLCAUSE, H5P_DEFAULT);
+
+ /* Set collective I/O properties in the dxpl. */
+ ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+
+ /* Read */
+ ret = H5Dread(dataset, data_type, mem_space, file_space, dxpl, 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, &no_collective_cause_local_read, &no_collective_cause_global_read);
+ VRFY((ret >= 0), "retriving no collective cause succeeded" );
+
+ /* Test values */
+ memset (message, 0, sizeof (message));
+ sprintf(message, "Local cause of Broken Collective I/O has the correct value for %s.\n",test_name);
+ VRFY((no_collective_cause_local_read == (uint32_t)no_collective_cause_local_expected), message);
+ memset (message, 0, sizeof (message));
+ sprintf(message, "Global cause of Broken Collective I/O has the correct value for %s.\n",test_name);
+ VRFY((no_collective_cause_global_read == (uint32_t)no_collective_cause_global_expected), message);
+
+ /* Release some resources */
+ if (sid)
+ H5Sclose(sid);
+ if (fapl_read)
+ H5Pclose(fapl_read);
+ if (dcpl)
+ H5Pclose(dcpl);
+ if (dxpl)
+ H5Pclose(dxpl);
+ if (dataset)
+ H5Dclose(dataset);
+ if (mem_space)
+ H5Sclose(mem_space);
+ if (file_space)
+ H5Sclose(file_space);
+ if (fid)
+ H5Fclose(fid);
+ HDfree(buffer);
+ 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)
+{
+ int mpi_size = -1;
+ int mpi_rank = -1;
+ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+ MPI_Comm_size(MPI_COMM_WORLD, &mpi_rank);
+
+ /*
+ * 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_SET_MPIPOSIX);
+ test_no_collective_cause_mode (TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES);
+ test_no_collective_cause_mode (TEST_POINT_SELECTIONS);
+ test_no_collective_cause_mode (TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT);
+ test_no_collective_cause_mode (TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL);
+#ifdef H5_HAVE_FILTER_FLETCHER32
+ /* TODO: use this instead of below TEST_FILTERS_READ when H5Dcreate and
+ * H5Dwrite is ready for mpio + filter feature.
+ */
+ /* test_no_collective_cause_mode (TEST_FILTERS); */
+ test_no_collective_cause_mode_filter (TEST_FILTERS_READ);
+#endif
+
+ /*
+ * Test combined causes
+ */
+ test_no_collective_cause_mode (TEST_SET_MPIPOSIX | TEST_DATATYPE_CONVERSION);
+ test_no_collective_cause_mode (TEST_DATATYPE_CONVERSION | TEST_DATA_TRANSFORMS);
+ test_no_collective_cause_mode (TEST_DATATYPE_CONVERSION | TEST_DATA_TRANSFORMS | TEST_POINT_SELECTIONS);
+
+ return;
+}
+
/*
* Test consistency semantics of atomic mode
*/
diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c
index be55f3c..9da2f6d 100644
--- a/testpar/testphdf5.c
+++ b/testpar/testphdf5.c
@@ -506,6 +506,10 @@ int main(int argc, char **argv)
"test actual io mode proprerty",
PARATESTFILE);
+ AddTest("nocolcause", no_collective_cause_tests, NULL,
+ "test cause for broken collective io",
+ PARATESTFILE);
+
if((mpi_size < 2) && MAINPROCESS) {
printf("File Image Ops daisy chain test needs at least 2 processes.\n");
printf("File Image Ops daisy chain test will be skipped \n");
diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h
index da11c62..29ad411 100644
--- a/testpar/testphdf5.h
+++ b/testpar/testphdf5.h
@@ -175,6 +175,21 @@ enum H5TEST_COLL_CHUNK_API {API_NONE=0,API_LINK_HARD,
#define TEST_ACTUAL_IO_LINK_CHUNK 9
#define TEST_ACTUAL_IO_CONTIGUOUS 10
+/* 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_SET_MPIPOSIX 0x010
+#define TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES 0x020
+#define TEST_POINT_SELECTIONS 0x040
+#define TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT 0x080
+#define TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_EXTERNAL 0x100
+#define TEST_FILTERS 0x200
+/* TEST_FILTERS will take place of this after supporting mpio + filter for
+ * H5Dcreate and H5Dwrite */
+#define TEST_FILTERS_READ 0x400
+
/* Don't erase these lines, they are put here for debugging purposes */
/*
#define MSPACE1_RANK 1
@@ -239,6 +254,7 @@ 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);