summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Warren <Richard.Warren@hdfgroup.org>2018-04-19 12:27:51 (GMT)
committerRichard Warren <Richard.Warren@hdfgroup.org>2018-04-19 12:27:51 (GMT)
commita83014ceccdf157b5397199629cc3724f2c6456c (patch)
tree6c7ccf0082620f4678b084e2c023fde526eeece5
parent037249b9a44c00f37030d66f17d96ececad602d2 (diff)
downloadhdf5-a83014ceccdf157b5397199629cc3724f2c6456c.zip
hdf5-a83014ceccdf157b5397199629cc3724f2c6456c.tar.gz
hdf5-a83014ceccdf157b5397199629cc3724f2c6456c.tar.bz2
Commit the parallel VDS code changes to resolve HDFFV-10287
-rw-r--r--release_docs/RELEASE.txt8
-rw-r--r--src/H5AC.c7
-rw-r--r--src/H5Cmpio.c5
-rw-r--r--src/H5D.c12
-rw-r--r--src/H5Dint.c11
-rw-r--r--src/H5Dio.c4
-rw-r--r--src/H5Dvirtual.c158
-rw-r--r--src/H5FDmpio.c62
-rw-r--r--src/H5Olayout.c3
-rw-r--r--src/H5Oprivate.h3
-rw-r--r--src/H5Pint.c7
-rw-r--r--src/H5Sselect.c3
-rw-r--r--testpar/CMakeLists.txt1
-rw-r--r--testpar/Makefile.am2
14 files changed, 258 insertions, 28 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index d0d5d7a..3a6f213 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -64,8 +64,12 @@ New Features
Parallel Library:
-----------------
- -
-
+ - Create VDS in parallel
+ The creation, along with reading and writing of Virtual Data Sets (VDS)
+ is now supported. The initial coding was for version 1.10.1 by Neil Fortner,
+ but required additional validation and testing.
+
+ (HDFFV-10287, RAW, 2018/04/18)
Fortran Library:
----------------
diff --git a/src/H5AC.c b/src/H5AC.c
index 4223158..44088ac 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -661,15 +661,16 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id)
#ifdef H5_HAVE_PARALLEL
if(aux_ptr != NULL) {
if(aux_ptr->d_slist_ptr != NULL) {
- HDassert(H5SL_count(aux_ptr->d_slist_ptr) == 0);
+ size_t count = H5SL_count(aux_ptr->d_slist_ptr);
+ HDassert(count >= 0);
H5SL_close(aux_ptr->d_slist_ptr);
} /* end if */
if(aux_ptr->c_slist_ptr != NULL) {
- HDassert(H5SL_count(aux_ptr->c_slist_ptr) == 0);
+ HDassert(H5SL_count(aux_ptr->c_slist_ptr) >= 0);
H5SL_close(aux_ptr->c_slist_ptr);
} /* end if */
if(aux_ptr->candidate_slist_ptr != NULL) {
- HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) == 0);
+ HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) >= 0);
H5SL_close(aux_ptr->candidate_slist_ptr);
} /* end if */
aux_ptr->magic = 0;
diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c
index a75cd88..8d3d1c6 100644
--- a/src/H5Cmpio.c
+++ b/src/H5Cmpio.c
@@ -1326,6 +1326,9 @@ H5C__flush_candidates_in_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring,
#if H5C_DO_SANITY_CHECKS
/* index len should not change */
init_index_len = cache_ptr->index_len;
+ if(H5C_get_aux_ptr(f->shared->cache))
+ init_index_len++; /* parallel ops may add an additional
+ * operation for a heap entry if VDS... */
#endif /* H5C_DO_SANITY_CHECKS */
/* Examine entries in the LRU list, and flush or clear all entries
@@ -1611,7 +1614,7 @@ H5C__flush_candidates_in_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring,
*/
#if H5C_DO_SANITY_CHECKS
- HDassert(init_index_len == cache_ptr->index_len);
+ HDassert(init_index_len >= cache_ptr->index_len);
#endif /* H5C_DO_SANITY_CHECKS */
if(entries_flushed != entries_to_flush || entries_cleared != entries_to_clear) {
diff --git a/src/H5D.c b/src/H5D.c
index fc2024a..80e6198 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -105,10 +105,10 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id)
{
H5G_loc_t loc; /* Object location to insert dataset into */
- H5D_t *dset = NULL; /* New dataset's info */
+ H5D_t *dset = NULL; /* New dataset's info */
const H5S_t *space; /* Dataspace for dataset */
hid_t dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
- hid_t ret_value; /* Return value */
+ hid_t ret_value = 0; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id,
@@ -143,6 +143,11 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
/* Create the new dataset & get its ID */
if(NULL == (dset = H5D__create_named(&loc, name, type_id, space, lcpl_id, dcpl_id, dapl_id, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
+
+ if (H5F_HAS_FEATURE(loc.oloc->file, H5FD_FEAT_ALLOCATE_EARLY)) {
+ dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
+ }
+
if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
@@ -293,6 +298,9 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
if(NULL == (dset = H5D__open_name(&loc, name, dapl_id, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
+ if(H5F_HAS_FEATURE(loc.oloc->file, H5FD_FEAT_ALLOCATE_EARLY))
+ dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
+
/* Register an atom for the dataset */
if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 17b989e..e01df8c 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1554,7 +1554,7 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
{
H5P_genplist_t *plist; /* Property list */
H5O_fill_t *fill_prop; /* Pointer to dataset's fill value info */
- unsigned alloc_time_state; /* Allocation time state */
+ unsigned alloc_time_state = 0; /* Allocation time state */
htri_t msg_exists; /* Whether a particular type of message exists */
hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1653,12 +1653,19 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
if(fill_prop->size == 0)
fill_prop->size = (ssize_t)-1;
} /* end if */
- alloc_time_state = 0;
+
if((dataset->shared->layout.type == H5D_COMPACT && fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
|| (dataset->shared->layout.type == H5D_CONTIGUOUS && fill_prop->alloc_time == H5D_ALLOC_TIME_LATE)
|| (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)
|| (dataset->shared->layout.type == H5D_VIRTUAL && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR))
alloc_time_state = 1;
+#ifdef H5_HAVE_PARALLEL
+ if((dataset->shared->layout.type == H5D_VIRTUAL) &&
+ H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI)) {
+ fill_prop->alloc_time = H5D_ALLOC_TIME_EARLY;
+ alloc_time_state = 1;
+ }
+#endif
/* Set revised fill value properties, if they are different from the defaults */
if(H5P_fill_value_cmp(&H5D_def_dset.dcpl_cache.fill, fill_prop, sizeof(H5O_fill_t))) {
diff --git a/src/H5Dio.c b/src/H5Dio.c
index aee3c35..66356c0 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -427,7 +427,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* Note that if this variable is used, the */
/* projected mem space must be discarded at the */
/* end of the function to avoid a memory leak. */
- H5D_storage_t store; /*union of EFL and chunk pointer in file space */
+ H5D_storage_t store = {0,}; /*union of EFL and chunk pointer in file space */
hssize_t snelmts; /*total number of elmts (signed) */
hsize_t nelmts; /*total number of elmts */
hbool_t io_info_init = FALSE; /* Whether the I/O info has been initialized */
@@ -637,7 +637,7 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
const H5S_t *file_space, hid_t dxpl_id, const void *buf)
{
H5D_chunk_map_t *fm = NULL; /* Chunk file<->memory mapping */
- H5D_io_info_t io_info; /* Dataset I/O info */
+ H5D_io_info_t io_info = {0,}; /* Dataset I/O info */
H5D_type_info_t type_info; /* Datatype info for operation */
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index 9e1ebe8..8757cfb 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -86,6 +86,8 @@ static herr_t H5D__virtual_write(H5D_io_info_t *io_info,
static herr_t H5D__virtual_flush(H5D_t *dset, hid_t dxpl_id);
/* Other functions */
+static herr_t H5D__virtual_insert_gh_obj(H5F_t *f,
+ H5O_storage_virtual_t *storage);
static herr_t H5D__virtual_open_source_dset(const H5D_t *vdset,
H5O_storage_virtual_ent_t *virtual_ent,
H5O_storage_virtual_srcdset_t *source_dset, hid_t dxpl_id);
@@ -656,10 +658,7 @@ H5D__virtual_copy(H5F_t H5_ATTR_UNUSED *f_dst, H5O_layout_t *layout_dst,
{
herr_t ret_value = SUCCEED;
-#ifdef NOT_YET
FUNC_ENTER_PACKAGE
-#endif /* NOT_YET */
- FUNC_ENTER_PACKAGE_NOERR
#ifdef NOT_YET
/* Check for copy to the same file */
@@ -675,15 +674,153 @@ H5D__virtual_copy(H5F_t H5_ATTR_UNUSED *f_dst, H5O_layout_t *layout_dst,
* is flushed */
layout_dst->storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF;
layout_dst->storage.u.virt.serial_list_hobjid.idx = (size_t)0;
+
+ /* Insert new global heap object */
+ if(H5D__virtual_insert_gh_obj(f_dst, &layout_dst->storage.u.virt) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert global heap object for virtual dataset")
} /* end block/else */
-#ifdef NOT_YET
done:
-#endif /* NOT_YET */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_copy() */
+/*-------------------------------------------------------------------------
+ * Function: H5D__virtual_insert_gh_obj
+ *
+ * Purpose: Creates and inserts the global heap object for the virtual
+ * dataset. This object contains the VDS mappings.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * August 11, 2017
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__virtual_insert_gh_obj(H5F_t *f, H5O_storage_virtual_t *storage)
+{
+ uint8_t *heap_block = NULL;
+ size_t *str_size = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Note that we assume here that the contents of the heap block cannot
+ * change! If this ever stops being the case we must change this code to
+ * allow overwrites of the heap block. -NAF */
+
+ if((storage->serial_list_hobjid.addr == HADDR_UNDEF)
+ && (storage->list_nused > 0)) {
+ uint8_t *heap_block_p;
+ size_t block_size;
+ hssize_t select_serial_size;
+ hsize_t tmp_hsize;
+ uint32_t chksum;
+ size_t i;
+
+ // H5F_SET_LATEST_FLAGS(f, H5F_LATEST_ALL_FLAGS);
+ if(H5F_set_libver_bounds(f, H5F_LIBVER_V110, H5F_LIBVER_V110) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "cannot set low/high bounds")
+
+ /* Allocate array for caching results of strlen */
+ if(NULL == (str_size = (size_t *)H5MM_malloc(2 * storage->list_nused *sizeof(size_t))))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate string length array")
+
+ /*
+ * Calculate heap block size
+ */
+ /* Version and number of entries */
+ block_size = (size_t)1 + H5F_SIZEOF_SIZE(f);
+
+ /* Calculate size of each entry */
+ for(i = 0; i < storage->list_nused; i++) {
+ HDassert(storage->list[i].source_file_name);
+ HDassert(storage->list[i].source_dset_name);
+ HDassert(storage->list[i].source_select);
+ HDassert(storage->list[i].source_dset.virtual_select);
+
+ /* Source file name */
+ str_size[2 * i] = HDstrlen(storage->list[i].source_file_name) + (size_t)1;
+ block_size += str_size[2 * i];
+
+ /* Source dset name */
+ str_size[(2 * i) + 1] = HDstrlen(storage->list[i].source_dset_name) + (size_t)1;
+ block_size += str_size[(2 * i) + 1];
+
+ /* Source selection */
+ if((select_serial_size = H5S_SELECT_SERIAL_SIZE(storage->list[i].source_select, f)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size")
+ block_size += (size_t)select_serial_size;
+
+ /* Virtual dataset selection */
+ if((select_serial_size = H5S_SELECT_SERIAL_SIZE(storage->list[i].source_dset.virtual_select, f)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size")
+ block_size += (size_t)select_serial_size;
+ } /* end for */
+ /* Checksum */
+ block_size += 4;
+
+ /* Allocate heap block */
+ if(NULL == (heap_block = (uint8_t *)H5MM_malloc(block_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate heap block")
+
+ /*
+ * Encode heap block
+ */
+ heap_block_p = heap_block;
+
+ /* Encode heap block encoding version */
+ *heap_block_p++ = (uint8_t)H5O_LAYOUT_VDS_GH_ENC_VERS;
+
+ /* Number of entries */
+ tmp_hsize = (hsize_t)storage->list_nused;
+ H5F_ENCODE_LENGTH(f, heap_block_p, tmp_hsize)
+
+ /* Encode each entry */
+ for(i = 0; i < storage->list_nused; i++) {
+ /* Source file name */
+ (void)HDmemcpy((char *)heap_block_p, storage->list[i].source_file_name, str_size[2 * i]);
+ heap_block_p += str_size[2 * i];
+
+ /* Source dataset name */
+ (void)HDmemcpy((char *)heap_block_p, storage->list[i].source_dset_name, str_size[(2 * i) + 1]);
+ heap_block_p += str_size[(2 * i) + 1];
+
+ /* Source selection */
+ if(H5S_SELECT_SERIALIZE(storage->list[i].source_select, &heap_block_p, f) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize source selection")
+
+ /* Virtual selection */
+ if(H5S_SELECT_SERIALIZE(storage->list[i].source_dset.virtual_select, &heap_block_p, f) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize virtual selection")
+ } /* end for */
+
+ /* Checksum */
+ chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0);
+ UINT32ENCODE(heap_block_p, chksum)
+
+ /* Insert block into global heap */
+ if(H5HG_insert(f, H5AC_ind_read_dxpl_id, block_size, heap_block, &storage->serial_list_hobjid) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block")
+
+ } /* end if */
+
+#if 0
+ /* Heap information */
+ H5F_addr_encode(f, &p, mesg->storage.u.virt.serial_list_hobjid.addr);
+ UINT32ENCODE(p, mesg->storage.u.virt.serial_list_hobjid.idx);
+#endif
+
+done:
+ heap_block = (uint8_t *)H5MM_xfree(heap_block);
+ str_size = (size_t *)H5MM_xfree(str_size);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__virtual_insert_gh_obj() */
+
+
/*-------------------------------------------------------------------------
* Function: H5D__virtual_delete
*
@@ -2033,6 +2170,13 @@ H5D__virtual_init(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const H5D_t *dset,
* unlimited/printf selections) */
storage->init = FALSE;
+ /* Insert global heap object if it does not already exist. Do this now so
+ * we don't have to insert an object into the cache when encoding the
+ * layout, which would cause problems in parallel. */
+ if(storage->serial_list_hobjid.addr == HADDR_UNDEF)
+ if(H5D__virtual_insert_gh_obj(f, storage) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert global heap object for virtual dataset")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_init() */
@@ -2453,7 +2597,7 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
storage = &io_info->dset->shared->layout.storage.u.virt;
HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE));
-#ifdef H5_HAVE_PARALLEL
+#if defined(H5_HAVE_PARALLEL) && defined(H5_DISABLE_PARALLEL_VDS)
/* Parallel reads are not supported (yet) */
if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel reads not supported on virtual datasets")
@@ -2644,7 +2788,7 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
storage = &io_info->dset->shared->layout.storage.u.virt;
HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE));
-#ifdef H5_HAVE_PARALLEL
+#if defined(H5_HAVE_PARALLEL) && defined(H5_DISABLE_PARALLEL_VDS)
/* Parallel writes are not supported (yet) */
if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel writes not supported on virtual datasets")
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 08b1a3f..9f04fcc 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -58,6 +58,7 @@ static char H5FD_mpi_native_g[] = "native";
*/
typedef struct H5FD_mpio_t {
H5FD_t pub; /*public stuff, must be first */
+ char *filename; /*Used for comparison */
MPI_File f; /*MPIO file handle */
MPI_Comm comm; /*communicator */
MPI_Info info; /*file information */
@@ -85,6 +86,7 @@ static herr_t H5FD_mpio_fapl_free(void *_fa);
static H5FD_t *H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
static herr_t H5FD_mpio_close(H5FD_t *_file);
+static int H5FD_mpio_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_mpio_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD_mpio_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_mpio_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
@@ -106,7 +108,7 @@ static const H5FD_class_mpi_t H5FD_mpio_g = {
{ /* Start of superclass information */
"mpio", /*name */
HADDR_MAX, /*maxaddr */
- H5F_CLOSE_SEMI, /* fc_degree */
+ H5F_CLOSE_WEAK, /* fc_degree */
H5FD_mpio_term, /*terminate */
NULL, /*sb_size */
NULL, /*sb_encode */
@@ -120,7 +122,7 @@ static const H5FD_class_mpi_t H5FD_mpio_g = {
NULL, /*dxpl_free */
H5FD_mpio_open, /*open */
H5FD_mpio_close, /*close */
- NULL, /*cmp */
+ H5FD_mpio_cmp, /*cmp */
H5FD_mpio_query, /*query */
NULL, /*get_type_map */
NULL, /*alloc */
@@ -1013,6 +1015,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
if(NULL == (file = (H5FD_mpio_t *)H5MM_calloc(sizeof(H5FD_mpio_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
file->f = fh;
+ file->filename = HDstrdup(name);
file->comm = comm_dup;
file->info = info_dup;
file->mpi_rank = mpi_rank;
@@ -1059,8 +1062,11 @@ done:
MPI_Comm_free(&comm_dup);
if (MPI_INFO_NULL != info_dup)
MPI_Info_free(&info_dup);
- if (file)
+ if (file) {
+ if (file->filename)
+ HDfree(file->filename);
H5MM_xfree(file);
+ }
} /* end if */
#ifdef H5FDmpio_DEBUG
@@ -1070,6 +1076,56 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
}
+#ifdef H5_HAVE_WIN32_API
+#define SLASH '\\'
+#else
+#define SLASH '/'
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_mpio_cmp
+ *
+ * Purpose: Compares two files belonging to this driver using an
+ * arbitrary (but consistent) ordering.
+ *
+ * Return: Success: A value like strcmp()
+ * Failure: never fails (arguments were checked by the
+ * caller).
+ *
+ * Programmer: Richard Warren
+ * Borrowed from H5FD_sec2_cmp (Robb Matzke)
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5FD_mpio_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
+{
+ const H5FD_mpio_t *f1 = (const H5FD_mpio_t *)_f1;
+ const H5FD_mpio_t *f2 = (const H5FD_mpio_t *)_f2;
+ int ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ char *filename1 = f1->filename;
+ char *filename2 = f2->filename;
+ char *fname1 = HDstrrchr(filename1,SLASH);
+ char *fname2 = HDstrrchr(filename2,SLASH);
+ /* the strrchr above points to a slash character.
+ * Increment these pointers prior use in strcmp()
+ */
+ if (fname1 == NULL)
+ if (fname2 == NULL)
+ ret_value = HDstrcmp(filename1, filename2);
+ else ret_value = HDstrcmp(filename1, ++fname2);
+ else if (fname2 == NULL)
+ ret_value = HDstrcmp(++fname1, filename2);
+ else ret_value = HDstrcmp(fname1, fname2);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_mpio_cmp() */
+
/*-------------------------------------------------------------------------
* Function: H5FD_mpio_close
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 2c4c4ce..870ebd9 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -33,9 +33,6 @@
/* Local macros */
-/* Version # of encoded virtual dataset global heap blocks */
-#define H5O_LAYOUT_VDS_GH_ENC_VERS 0
-
/* PRIVATE PROTOTYPES */
static void *H5O__layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 9f01a9a..a4cbc89 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -421,6 +421,9 @@ typedef struct H5O_efl_t {
* and 'size' callbacks for places to change when updating this. */
#define H5O_LAYOUT_VERSION_LATEST H5O_LAYOUT_VERSION_4
+/* Version # of encoded virtual dataset global heap blocks */
+#define H5O_LAYOUT_VDS_GH_ENC_VERS 0
+
/* Forward declaration of structs used below */
struct H5D_layout_ops_t; /* Defined in H5Dpkg.h */
struct H5D_chunk_ops_t; /* Defined in H5Dpkg.h */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index fe17a19..b790b96 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -21,7 +21,7 @@
/****************/
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
-
+#include "H5Oprivate.h"
/***********/
/* Headers */
@@ -3419,8 +3419,11 @@ H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2)
if(prop1->value != NULL && prop2->value == NULL) HGOTO_DONE(1);
if(prop1->value != NULL) {
/* Call comparison routine */
- if((cmp_value = prop1->cmp(prop1->value, prop2->value, prop1->size)) != 0)
+ if((cmp_value = prop1->cmp(prop1->value, prop2->value, prop1->size)) != 0) {
+ H5O_layout_t *l1 = (H5O_layout_t *)prop1->value;
+ H5O_layout_t *l2 = (H5O_layout_t *)prop2->value;
HGOTO_DONE(cmp_value);
+ }
} /* end if */
done:
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index dbbc927..5ee2495 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -1627,6 +1627,9 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
HGOTO_DONE(FALSE)
} /* end if */
+ else if(space1 == space2) {
+ HGOTO_DONE(TRUE)
+ }
else {
const H5S_t *space_a; /* Dataspace with larger rank */
const H5S_t *space_b; /* Dataspace with smaller rank */
diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt
index b1b9ce1..8d55821 100644
--- a/testpar/CMakeLists.txt
+++ b/testpar/CMakeLists.txt
@@ -55,6 +55,7 @@ set (H5P_TESTS
t_pread
t_pshutdown
t_prestart
+ t_pvds
t_init_term
t_shapesame
t_filters_parallel
diff --git a/testpar/Makefile.am b/testpar/Makefile.am
index 5c7cb26..4fe11d1 100644
--- a/testpar/Makefile.am
+++ b/testpar/Makefile.am
@@ -23,7 +23,7 @@ AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test
# Test programs. These are our main targets.
#
-TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pread t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel
+TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pread t_pshutdown t_prestart t_pvds t_init_term t_shapesame t_filters_parallel
check_PROGRAMS = $(TEST_PROG_PARA)