diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/H5Cdbg.c | 107 | ||||
-rw-r--r-- | src/H5Cmpio.c | 102 | ||||
-rw-r--r-- | src/H5Cprivate.h | 5 | ||||
-rw-r--r-- | src/H5Dearray.c | 15 | ||||
-rw-r--r-- | src/H5FDmpi.c | 39 | ||||
-rw-r--r-- | src/H5FDmpio.c | 37 | ||||
-rw-r--r-- | src/H5FDprivate.h | 2 | ||||
-rw-r--r-- | src/H5Fmpi.c | 26 | ||||
-rw-r--r-- | src/H5Fprivate.h | 1 | ||||
-rw-r--r-- | src/H5L.c | 6 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5PL.c | 282 | ||||
-rw-r--r-- | src/H5PLpkg.h | 50 | ||||
-rw-r--r-- | src/H5PLpublic.h | 7 |
15 files changed, 628 insertions, 53 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9321bbd..e2acd30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -520,6 +520,7 @@ set (H5PL_SOURCES set (H5PL_HDRS ${HDF5_SRC_DIR}/H5PLextern.h + ${HDF5_SRC_DIR}/H5PLpkg.h ${HDF5_SRC_DIR}/H5PLpublic.h ) IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SOURCES}" ) diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c index 0bb00d7..4a08d9b 100644 --- a/src/H5Cdbg.c +++ b/src/H5Cdbg.c @@ -28,12 +28,16 @@ #include "H5Cmodule.h" /* This source code file is part of the H5C module */ +#define H5AC_FRIEND + + + /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata Cache */ +#include "H5ACpkg.h" /* Metadata Cache */ #include "H5Cpkg.h" /* Cache */ #include "H5Eprivate.h" /* Error Handling */ @@ -338,6 +342,107 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn) /*------------------------------------------------------------------------- + * Function: H5C_dump_coll_write_list + * + * Purpose: Debugging routine that prints a summary of the contents of + * the collective write skip list used by the metadata cache + * in the parallel case to maintain a list of entries to write + * collectively at a sync point. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 4/1/17 + * + *------------------------------------------------------------------------- + */ +#ifdef H5_HAVE_PARALLEL +#ifndef NDEBUG +herr_t +H5C_dump_coll_write_list(H5C_t * cache_ptr, char * calling_fcn) +{ + herr_t ret_value = SUCCEED; /* Return value */ + int i; + int list_len; + H5AC_aux_t * aux_ptr = NULL; + H5C_cache_entry_t * entry_ptr = NULL; + H5SL_node_t * node_ptr = NULL; + + FUNC_ENTER_NOAPI_NOERR + + HDassert(cache_ptr != NULL); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(cache_ptr->aux_ptr); + + aux_ptr = (H5AC_aux_t *)cache_ptr->aux_ptr; + + HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); + + HDassert(calling_fcn != NULL); + + list_len = (int)H5SL_count(cache_ptr->coll_write_list); + + HDfprintf(stdout, "\n\nDumping MDC coll write list from %d:%s.\n", + aux_ptr->mpi_rank, calling_fcn); + HDfprintf(stdout, " slist len = %u.\n", cache_ptr->slist_len); + + if ( list_len > 0 ) { + + /* scan the collective write list generating the desired output */ + HDfprintf(stdout, + "Num: Addr: Len: Prot/Pind: Dirty: Type:\n"); + + i = 0; + + node_ptr = H5SL_first(cache_ptr->coll_write_list); + + if ( node_ptr != NULL ) + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + else + + entry_ptr = NULL; + + while ( entry_ptr != NULL ) { + + HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + + HDfprintf(stdout, + "%s%d 0x%016llx %4lld %d/%d %d %s\n", + cache_ptr->prefix, i, + (long long)(entry_ptr->addr), + (long long)(entry_ptr->size), + (int)(entry_ptr->is_protected), + (int)(entry_ptr->is_pinned), + (int)(entry_ptr->is_dirty), + entry_ptr->type->name); + + node_ptr = H5SL_next(node_ptr); + + if ( node_ptr != NULL ) + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + else + + entry_ptr = NULL; + + i++; + + } /* end while */ + } /* end if */ + + HDfprintf(stdout, "\n\n"); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C_dump_coll_write_list() */ +#endif /* NDEBUG */ +#endif /* H5_HAVE_PARALLEL */ + + +/*------------------------------------------------------------------------- * Function: H5C_set_prefix * * Purpose: Set the values of the prefix field of H5C_t. This diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c index a4afcd4..a75cd88 100644 --- a/src/H5Cmpio.c +++ b/src/H5Cmpio.c @@ -948,12 +948,15 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) /* Get original transfer mode */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, \ + "not a data transfer property list") + if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &orig_xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") /* Get number of entries in collective write list */ count = (int)H5SL_count(cache_ptr->coll_write_list); + if(count > 0) { H5FD_mpio_xfer_t xfer_mode = H5FD_MPIO_COLLECTIVE; H5SL_node_t *node; @@ -962,21 +965,34 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) int i; if(H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O property") /* Allocate arrays */ - if(NULL == (length_array = (int *)H5MM_malloc((size_t)count * sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective write table length array") - if(NULL == (buf_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective buf table length array") - if(NULL == (offset_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective offset table length array") + if ( NULL == (length_array = + (int *)H5MM_malloc((size_t)count * sizeof(int))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective write table length array") + + if ( NULL == (buf_array = + (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective buf table length array") + + if(NULL == (offset_array = + (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective offset table length array") /* Fill arrays */ node = H5SL_first(cache_ptr->coll_write_list); HDassert(node); if(NULL == (entry_ptr = (H5C_cache_entry_t *)H5SL_item(node))) - HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, \ + "can't retrieve skip list item") /* Set up initial array position & buffer base address */ length_array[0] = (int)entry_ptr->size; @@ -987,8 +1003,10 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) node = H5SL_next(node); i = 1; while(node) { + if(NULL == (entry_ptr = (H5C_cache_entry_t *)H5SL_item(node))) - HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, \ + "can't retrieve skip list item") /* Set up array position */ length_array[i] = (int)entry_ptr->size; @@ -1001,48 +1019,85 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) } /* end while */ /* Create memory MPI type */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, buf_array, MPI_BYTE, &btype))) + if(MPI_SUCCESS != (mpi_code = + MPI_Type_create_hindexed(count, length_array, + buf_array, MPI_BYTE, + &btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + btype_created = TRUE; + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) /* Create file MPI type */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, offset_array, MPI_BYTE, &ftype))) + if(MPI_SUCCESS != (mpi_code = + MPI_Type_create_hindexed(count, length_array, + offset_array, MPI_BYTE, + &ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + ftype_created = TRUE; + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) /* Pass buf type, file type to the file driver */ if(H5FD_mpi_setup_collective(dxpl_id, &btype, &ftype) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O properties") /* Write data */ - if(H5F_block_write(f, H5FD_MEM_DEFAULT, (haddr_t)0, (size_t)1, dxpl_id, base_buf) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to write entries collectively") + if(H5F_block_write(f, H5FD_MEM_DEFAULT, (haddr_t)0, + (size_t)1, dxpl_id, base_buf) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "unable to write entries collectively") + } /* end if */ else { MPI_Status mpi_stat; - MPI_File mpi_fh_p; + MPI_File *mpi_fh_p; MPI_File mpi_fh; + MPI_Info *info_p; + MPI_Info info; if(H5F_get_mpi_handle(f, (MPI_File **)&mpi_fh_p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, \ + "can't get mpi file handle") + mpi_fh = *(MPI_File*)mpi_fh_p; - /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) + if (H5F_get_mpi_info(f, &info_p) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, \ + "can't get mpi file info") + + info = *info_p; + + /* just to match up with the 1st MPI_File_set_view from + * H5FD_mpio_write() + */ + if(MPI_SUCCESS != (mpi_code = + MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, + MPI_BYTE, "native", + info))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) /* just to match up with MPI_File_write_at_all from H5FD_mpio_write() */ HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); - if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, NULL, 0, MPI_BYTE, &mpi_stat))) + if(MPI_SUCCESS != (mpi_code = + MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, + NULL, 0, MPI_BYTE, &mpi_stat))) HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) - /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) + /* just to match up with the 2nd MPI_File_set_view (reset) in + * H5FD_mpio_write() + */ + if(MPI_SUCCESS != (mpi_code = + MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, + MPI_BYTE, "native", + info))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + } /* end else */ done: @@ -1061,7 +1116,8 @@ done: if(orig_xfer_mode != H5FD_MPIO_COLLECTIVE) { HDassert(plist); if(H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &orig_xfer_mode) < 0) - HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O property") } /* end if */ FUNC_LEAVE_NOAPI(ret_value); diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index eb4c681..5335f80 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -2338,9 +2338,12 @@ H5_DLL herr_t H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name); H5_DLL hbool_t H5C_get_serialization_in_progress(const H5C_t *cache_ptr); H5_DLL hbool_t H5C_cache_is_clean(const H5C_t *cache_ptr, H5C_ring_t inner_ring); H5_DLL herr_t H5C_dump_cache_skip_list(H5C_t *cache_ptr, char *calling_fcn); +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5C_dump_coll_write_list(H5C_t * cache_ptr, char * calling_fcn); +#endif /* H5_HAVE_PARALLEL */ H5_DLL herr_t H5C_get_entry_ptr_from_addr(H5C_t *cache_ptr, haddr_t addr, void **entry_ptr_ptr); -H5_DLL herr_t H5C_flush_dependency_exists(H5C_t *cache_ptr, haddr_t parent_addr, +H5_DLL herr_t H5C_flush_dependency_exists(H5C_t *cache_ptr, haddr_t parent_addr, haddr_t child_addr, hbool_t *fd_exists_ptr); H5_DLL herr_t H5C_verify_entry_type(H5C_t *cache_ptr, haddr_t addr, const H5C_class_t *expected_type, hbool_t *in_cache_ptr, diff --git a/src/H5Dearray.c b/src/H5Dearray.c index eb8d702..1df0a58 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -1135,7 +1135,7 @@ H5D__earray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *uda H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim); /* Calculate the index of this chunk */ - idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks); + idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_max_down_chunks); } /* end if */ else { /* Calculate the index of this chunk */ @@ -1200,7 +1200,8 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) /* "Swizzle" constant dimensions for this dataset */ if(layout->u.earray.unlim_dim > 0) { - hsize_t swizzled_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of # of chunks in each dimension */ + hsize_t swizzled_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of # of chunks in each dimension */ + hsize_t swizzled_max_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of max # of chunks in each dimension */ /* Get the swizzled chunk dimensions */ HDmemcpy(layout->u.earray.swizzled_dim, layout->dim, (layout->ndims - 1) * sizeof(layout->dim[0])); @@ -1213,6 +1214,14 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) /* Get the swizzled "down" sizes for each dimension */ if(H5VM_array_down((layout->ndims - 1), swizzled_chunks, layout->u.earray.swizzled_down_chunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") + + /* Get the swizzled max number of chunks in each dimension */ + HDmemcpy(swizzled_max_chunks, layout->max_chunks, (layout->ndims - 1) * sizeof(swizzled_max_chunks[0])); + H5VM_swizzle_coords(hsize_t, swizzled_max_chunks, layout->u.earray.unlim_dim); + + /* Get the swizzled max "down" sizes for each dimension */ + if(H5VM_array_down((layout->ndims - 1), swizzled_max_chunks, layout->u.earray.swizzled_max_down_chunks) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") } /* end if */ done: @@ -1412,7 +1421,7 @@ H5D__earray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim); /* Calculate the index of this chunk */ - idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks); + idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_max_down_chunks); } /* end if */ else { /* Calculate the index of this chunk */ diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c index 3b2cdef..16be455 100644 --- a/src/H5FDmpi.c +++ b/src/H5FDmpi.c @@ -146,6 +146,45 @@ done: /*------------------------------------------------------------------------- + * Function: H5FD_get_mpi_info + * + * Purpose: Retrieves the file's mpi info + * + * Return: Success: SUCCEED + * + * Failure: Negative + * + * Programmer: John Mainzer + * 4/4/17 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_get_mpi_info(H5FD_t *file, void** mpi_info) +{ + const H5FD_class_mpi_t *cls; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(file); + cls = (const H5FD_class_mpi_t *)(file->cls); + HDassert(cls); + HDassert(cls->get_mpi_info); /* All MPI drivers must implement this */ + + /* Dispatch to driver */ + if ((ret_value=(cls->get_mpi_info)(file, mpi_info)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, \ + "driver get_mpi_info request failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_get_mpi_info() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_mpi_MPIOff_to_haddr * * Purpose: Convert an MPI_Offset value to haddr_t. diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 3d55f3d..ace91f8 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -93,6 +93,7 @@ static herr_t H5FD_mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static int H5FD_mpio_mpi_rank(const H5FD_t *_file); static int H5FD_mpio_mpi_size(const H5FD_t *_file); static MPI_Comm H5FD_mpio_communicator(const H5FD_t *_file); +static herr_t H5FD_mpio_get_info(H5FD_t *_file, void** mpi_info); /* The MPIO file driver information */ static const H5FD_class_mpi_t H5FD_mpio_g = { @@ -132,7 +133,8 @@ static const H5FD_class_mpi_t H5FD_mpio_g = { }, /* End of superclass information */ H5FD_mpio_mpi_rank, /*get_rank */ H5FD_mpio_mpi_size, /*get_size */ - H5FD_mpio_communicator /*get_comm */ + H5FD_mpio_communicator, /*get_comm */ + H5FD_mpio_get_info /*get_info */ }; #ifdef H5FDmpio_DEBUG @@ -1306,6 +1308,39 @@ done: /*------------------------------------------------------------------------- + * Function: H5FD_mpio_get_info + * + * Purpose: Returns the file info of MPIO file driver. + * + * Returns: Non-negative if succeed or negative if fails. + * + * Programmer: John Mainzer + * April 4, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- +*/ +static herr_t +H5FD_mpio_get_info(H5FD_t *_file, void** mpi_info) +{ + H5FD_mpio_t *file = (H5FD_mpio_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + if(!mpi_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mpi info not valid") + + *mpi_info = &(file->info); + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5FD_mpio_get_info() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_mpio_read * * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index e3e1b22..0fc2135 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -51,6 +51,7 @@ typedef struct H5FD_class_mpi_t { int (*get_rank)(const H5FD_t *file); /* Get the MPI rank of a process */ int (*get_size)(const H5FD_t *file); /* Get the MPI size of a communicator */ MPI_Comm (*get_comm)(const H5FD_t *file); /* Get the communicator for a file */ + herr_t (*get_mpi_info)(H5FD_t *file, void** mpi_info); /* get MPI_Info for a file */ } H5FD_class_mpi_t; #endif @@ -200,6 +201,7 @@ H5_DLL herr_t H5FD_get_mpio_atomicity(H5FD_t *file, hbool_t *flag); H5_DLL int H5FD_mpi_get_rank(const H5FD_t *file); H5_DLL int H5FD_mpi_get_size(const H5FD_t *file); H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file); +H5_DLL herr_t H5FD_get_mpi_info(H5FD_t *file, void** file_info); #endif /* H5_HAVE_PARALLEL */ #endif /* !_H5FDprivate_H */ diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index e4b4fc8..2ce454a 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -354,5 +354,31 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_mpi_retrieve_comm */ +/*------------------------------------------------------------------------- + * Function: H5F_get_mpi_info + * + * Purpose: Retrieves MPI File info. + * + * Return: Success: The size (positive) + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_mpi_info(const H5F_t *f, MPI_Info **f_info) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(f && f->shared); + + /* Dispatch to driver */ + if ((ret_value = H5FD_get_mpi_info(f->shared->lf, (void **)f_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_mpi_info() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index f3aa46d..6f68a62 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -850,6 +850,7 @@ H5_DLL int H5F_mpi_get_rank(const H5F_t *f); H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_mpi_get_size(const H5F_t *f); H5_DLL herr_t H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm); +H5_DLL herr_t H5F_get_mpi_info(const H5F_t *f, MPI_Info **f_info); #endif /* H5_HAVE_PARALLEL */ /* External file cache routines */ @@ -2349,9 +2349,11 @@ H5L_delete_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, if(name == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - /* Check for removing '.' */ + /* Check for non-existent (NULL) link. + * Note that this can also occur when attempting to remove '.' + */ if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "can't delete self") + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "callback link pointer is NULL (specified link may be '.' or not exist)") /* Remove the link from the group */ if(H5G_obj_remove(grp_loc->oloc, grp_loc->path->full_path_r, name, udata->dxpl_id) < 0) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index e82bf1b..0f798b2 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -582,6 +582,7 @@ typedef struct H5O_layout_chunk_earray_t { unsigned unlim_dim; /* Rank of unlimited dimension for dataset */ uint32_t swizzled_dim[H5O_LAYOUT_NDIMS]; /* swizzled chunk dimensions */ hsize_t swizzled_down_chunks[H5O_LAYOUT_NDIMS]; /* swizzled "down" size of number of chunks in each dimension */ + hsize_t swizzled_max_down_chunks[H5O_LAYOUT_NDIMS]; /* swizzled max "down" size of number of chunks in each dimension */ } H5O_layout_chunk_earray_t; typedef struct H5O_layout_chunk_bt2_t { @@ -23,15 +23,33 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5MMprivate.h" /* Memory management */ -#include "H5PLprivate.h" /* Plugin */ +#include "H5PLpkg.h" /* Plugin */ #include "H5Zprivate.h" /* Filter pipeline */ /****************/ /* Local Macros */ /****************/ - -#define H5PL_MAX_PATH_NUM 16 +#ifdef H5_HAVE_WIN32_API +#define H5PL_EXPAND_ENV_VAR { \ + long bufCharCount; \ + char *tempbuf; \ + if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) \ + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") \ + if((bufCharCount = ExpandEnvironmentStringsA(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { \ + tempbuf = (char *)H5MM_xfree(tempbuf); \ + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") \ + } \ + if(bufCharCount == 0) { \ + tempbuf = (char *)H5MM_xfree(tempbuf); \ + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") \ + } \ + dl_path = (char *)H5MM_xfree(dl_path); \ + dl_path = tempbuf; \ + } +#else +#define H5PL_EXPAND_ENV_VAR +#endif /* H5_HAVE_WIN32_API */ /****************************/ /* Macros for supporting @@ -388,6 +406,244 @@ done: /*------------------------------------------------------------------------- + * Function: H5PLappend + * + * Purpose: Insert a plugin path at the end of the list. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLappend(const char* plugin_path) +{ + herr_t ret_value = SUCCEED; /* Return value */ + char *dl_path = NULL; + + FUNC_ENTER_API(FAIL) + if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") + if(NULL == plugin_path) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + H5PL_EXPAND_ENV_VAR + + H5PL_path_table_g[H5PL_num_paths_g] = dl_path; + H5PL_num_paths_g++; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLappend() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLprepend + * + * Purpose: Insert a plugin path at the beginning of the list. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLprepend(const char* plugin_path) +{ + herr_t ret_value = SUCCEED; /* Return value */ + char *dl_path = NULL; + unsigned int plindex; + + FUNC_ENTER_API(FAIL) + if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") + if(NULL == plugin_path) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + H5PL_EXPAND_ENV_VAR + + for (plindex = (unsigned int)H5PL_num_paths_g; plindex > 0; plindex--) + H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1]; + H5PL_path_table_g[0] = dl_path; + H5PL_num_paths_g++; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLprepend() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLreplace + * + * Purpose: Replace the path at the specified index. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLreplace(const char* plugin_path, unsigned int index) +{ + herr_t ret_value = SUCCEED; /* Return value */ + char *dl_path = NULL; + + FUNC_ENTER_API(FAIL) + if(NULL == plugin_path) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + H5PL_EXPAND_ENV_VAR + + if(H5PL_path_table_g[index]) + H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]); + H5PL_path_table_g[index] = dl_path; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLreplace() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLinsert + * + * Purpose: Insert a plugin path at the specified index, moving other paths after the index. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLinsert(const char* plugin_path, unsigned int index) +{ + herr_t ret_value = SUCCEED; /* Return value */ + char *dl_path = NULL; + unsigned int plindex; + + FUNC_ENTER_API(FAIL) + if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") + if(NULL == plugin_path) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + H5PL_EXPAND_ENV_VAR + + for(plindex = (unsigned int)H5PL_num_paths_g; plindex > index; plindex--) + H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1]; + H5PL_path_table_g[index] = dl_path; + H5PL_num_paths_g++; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLinsert() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLremove + * + * Purpose: Remove the plugin path at the specifed index and compacting the list. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLremove(unsigned int index) +{ + herr_t ret_value = SUCCEED; /* Return value */ + unsigned int plindex; + + FUNC_ENTER_API(FAIL) + if(H5PL_num_paths_g == 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table") + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == H5PL_path_table_g[index]) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index") + H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]); + + H5PL_num_paths_g--; + for(plindex = index; plindex < (unsigned int)H5PL_num_paths_g; plindex++) + H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex + 1]; + H5PL_path_table_g[H5PL_num_paths_g] = NULL; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLremove() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLget + * + * Purpose: Query the plugin path at the specified index. + * + * Return: Success: The length of path. + * + * If `pathname' is non-NULL then write up to `size' bytes into that + * buffer and always return the length of the pathname. + * Otherwise `size' is ignored and the function does not store the pathname, + * just returning the number of characters required to store the pathname. + * If an error occurs then the buffer pointed to by `pathname' (NULL or non-NULL) + * is unchanged and the function returns a negative value. + * If a zero is returned for the name's length, then there is no pathname + * associated with the index. + * + *------------------------------------------------------------------------- + */ +ssize_t +H5PLget(unsigned int index, char *pathname/*out*/, size_t size) +{ + ssize_t ret_value = 0; /* Return value */ + ssize_t len = 0; /* Length of pathname */ + char *dl_path = NULL; + + FUNC_ENTER_API(FAIL) + if(H5PL_num_paths_g == 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table") + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5PL_path_table_g[index])) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index") + len = HDstrlen(dl_path); + if(pathname) { + HDstrncpy(pathname, dl_path, MIN((size_t)(len + 1), size)); + if((size_t)len >= size) + pathname[size - 1] = '\0'; + } /* end if */ + + /* Set return value */ + ret_value = len; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLget() */ + + +/*------------------------------------------------------------------------- + * Function: H5PLsize + * + * Purpose: Query the size of the current list of plugin paths. + * + * Return: Non-negative or success. + * + *------------------------------------------------------------------------- + */ +unsigned int +H5PLsize(void) +{ + return (unsigned int)H5PL_num_paths_g; +} /* end H5PLsize() */ + + +/*------------------------------------------------------------------------- * Function: H5PL__init_path_table * * Purpose: Initialize the path table. @@ -420,25 +676,7 @@ H5PL__init_path_table(void) if(NULL == dl_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if(bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ + H5PL_EXPAND_ENV_VAR /* Put paths in the path table. They are separated by ":" */ dir = HDstrtok(dl_path, H5PL_PATH_SEPARATOR); diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h new file mode 100644 index 0000000..5cf3096 --- /dev/null +++ b/src/H5PLpkg.h @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#if !(defined H5PL_FRIEND || defined H5PL_MODULE) +#error "Do not include this file outside the H5PL package!" +#endif + +#ifndef _H5PLpkg_H +#define _H5PLpkg_H + +/* Include private header file */ +#include "H5PLprivate.h" /* Filter functions */ + +/* Other private headers needed by this file */ + +/**************************/ +/* Package Private Macros */ +/**************************/ + +#define H5PL_MAX_PATH_NUM 16 + + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Package Private Variables */ +/*****************************/ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ + +#endif /* _H5PLpkg_H */ + diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h index 5b80a5c..fc638a0 100644 --- a/src/H5PLpublic.h +++ b/src/H5PLpublic.h @@ -42,6 +42,13 @@ extern "C" { /* plugin state */ H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_type); H5_DLL herr_t H5PLget_loading_state(unsigned int* plugin_type/*out*/); +H5_DLL herr_t H5PLappend(const char* plugin_path); +H5_DLL herr_t H5PLprepend(const char* plugin_path); +H5_DLL herr_t H5PLreplace(const char* plugin_path, unsigned int index); +H5_DLL herr_t H5PLinsert(const char* plugin_path, unsigned int index); +H5_DLL herr_t H5PLremove(unsigned int index); +H5_DLL ssize_t H5PLget(unsigned int index, char *pathname/*out*/, size_t size); +H5_DLL unsigned int H5PLsize(void); #ifdef __cplusplus } |