diff options
-rw-r--r-- | release_docs/RELEASE.txt | 8 | ||||
-rw-r--r-- | src/H5D.c | 2 | ||||
-rw-r--r-- | src/H5Dprivate.h | 2 | ||||
-rw-r--r-- | src/H5FDmpio.c | 58 | ||||
-rw-r--r-- | src/H5FDmpio.h | 3 | ||||
-rw-r--r-- | src/H5Smpio.c | 244 |
6 files changed, 219 insertions, 98 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 453a503..02c9ab0 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -71,11 +71,15 @@ New Features o Parallel Library ================== + * Changed MPI I/O routines to avoid creating MPI derived types (and thus + needing to set the file view) for contiguous selections within datasets, + which should result in some performance improvement for those types of + selections. QAK - 2002/06/18 * Enable MPI type support for collective I/O to be enabled by default. This can be disabled by setting the HDF5_MPI_OPT_TYPES environment variable to the value "0". QAK - 2002/06/14 - * Allow chunks in chunked datasets to be cached when file is opened for - read-only access (bug #709). QAK - 2002/06/10 + * Allow chunks in chunked datasets to be cached when parallel file is + opened for read-only access (bug #709). QAK - 2002/06/10 * Changed method for allocating chunked dataset blocks to only allocate blocks that don't already exist, instead of attempting to create all the blocks all the time. This improves performance for chunked @@ -99,7 +99,7 @@ H5D_xfer_t H5D_xfer_dflt = { /*transaction */ #endif #ifdef H5_HAVE_PARALLEL - 0, /* Whether to use types for this I/O */ + 0, /* Whether to use a view for this I/O */ MPI_DATATYPE_NULL, /* MPI type for buffer (memory) */ MPI_DATATYPE_NULL, /* MPI type for file */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index ca277a6..f260253 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -73,7 +73,7 @@ typedef struct H5D_xfer_t { /*transaction */ #endif #ifdef H5_HAVE_PARALLEL - unsigned use_types; /* Whether to use types for this I/O */ + unsigned use_view; /* Whether to use a view for this I/O */ MPI_Datatype btype; /* MPI type for buffer (memory) */ MPI_Datatype ftype; /* MPI type for file */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 80c1c63..15e42c5 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -70,7 +70,7 @@ typedef struct H5FD_mpio_t { haddr_t eof; /*end-of-file marker */ haddr_t eoa; /*end-of-address marker */ haddr_t last_eoa; /* Last known end-of-address marker */ - int old_use_types; /*remember value of use_types */ + unsigned old_use_view; /*remember value of use_view */ } H5FD_mpio_t; /* Prototypes */ @@ -521,7 +521,7 @@ H5FD_mpio_mpi_size(H5FD_t *_file) *------------------------------------------------------------------------- */ herr_t -H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, MPI_Datatype ftype) +H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, MPI_Datatype ftype, unsigned use_view) { H5D_xfer_t *xfer_parms = NULL; @@ -537,7 +537,7 @@ H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, MPI_Datatype ftype) xfer_parms->btype = btype; xfer_parms->ftype = ftype; - xfer_parms->use_types = 1; + xfer_parms->use_view = use_view; FUNC_LEAVE(SUCCEED); } @@ -575,7 +575,7 @@ H5FD_mpio_teardown(hid_t dxpl_id) xfer_parms->btype = MPI_DATATYPE_NULL; xfer_parms->ftype = MPI_DATATYPE_NULL; - xfer_parms->use_types = 0; + xfer_parms->use_view = 0; FUNC_LEAVE(SUCCEED); } @@ -1193,7 +1193,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add MPI_Status mpi_stat; MPI_Datatype buf_type, file_type; int size_i, bytes_read, n; - int use_types_this_time, used_types_last_time; + unsigned use_view_this_time=0, used_view_last_time; herr_t ret_value=SUCCEED; FUNC_ENTER(H5FD_mpio_read, FAIL); @@ -1240,12 +1240,12 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add /* * Set up for a fancy xfer using complex types, or single byte block. We - * wouldn't need to rely on the use_types field if MPI semantics allowed + * wouldn't need to rely on the use_view field if MPI semantics allowed * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which * could mean "use MPI_BYTE" by convention). */ - use_types_this_time = xfer_parms->use_types; - if (use_types_this_time) { + use_view_this_time = xfer_parms->use_view; + if (use_view_this_time) { /* prepare for a full-blown xfer using btype, ftype, and disp */ buf_type = xfer_parms->btype; file_type = xfer_parms->ftype; @@ -1269,20 +1269,16 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add * Don't bother to reset the view if we're not using the types this time, * and did we didn't use them last time either. */ - used_types_last_time = file->old_use_types; - if (used_types_last_time || /* change to new ftype or MPI_BYTE */ - use_types_this_time) { /* almost certainly a different ftype */ + used_view_last_time = file->old_use_view; + if (used_view_last_time || /* change to new ftype or MPI_BYTE */ + use_view_this_time) { /* almost certainly a different ftype */ /*OKAY: CAST DISCARDS CONST QUALIFIER*/ if (MPI_SUCCESS != MPI_File_set_view(file->f, mpi_disp, MPI_BYTE, file_type, (char*)"native", file->info)) HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_File_set_view failed"); } - /* - * We always set the use_types flag to 0 because the default is not to - * use types next time, unless someone explicitly requests it by setting - * this flag to !=0. - */ - file->old_use_types = use_types_this_time; + /* Keep the 'use view' flag around for the next I/O */ + file->old_use_view = use_view_this_time; /* Read the data. */ assert(H5FD_MPIO_INDEPENDENT==dx->xfer_mode || H5FD_MPIO_COLLECTIVE==dx->xfer_mode); @@ -1308,7 +1304,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add /* Calling MPI_Get_count with "MPI_BYTE" is only valid when we actually * had the 'buf_type' set to MPI_BYTE -QAK */ - if(use_types_this_time) { + if(use_view_this_time) { /* Figure out the mapping from the MPI 'buf_type' to bytes, someday... * If this gets fixed (and MPI_Get_count() is reliable), the * kludge below where the 'bytes_read' value from MPI_Get_count() is @@ -1343,7 +1339,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add * reading past logical end of HDF5 file??? */ if ((n=(size_i-bytes_read)) > 0) { - if (use_types_this_time) { + if (use_view_this_time) { /* * INCOMPLETE rky 1998-09-18 * Haven't implemented reading zeros beyond EOF. What to do??? @@ -1487,7 +1483,7 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, MPI_Status mpi_stat; MPI_Datatype buf_type, file_type; int size_i, bytes_written; - int use_types_this_time, used_types_last_time; + unsigned use_view_this_time=0, used_view_last_time; herr_t ret_value=SUCCEED; FUNC_ENTER(H5FD_mpio_write, FAIL); @@ -1534,12 +1530,12 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, /* * Set up for a fancy xfer using complex types, or single byte block. We - * wouldn't need to rely on the use_types field if MPI semantics allowed + * wouldn't need to rely on the use_view field if MPI semantics allowed * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which * could mean "use MPI_BYTE" by convention). */ - use_types_this_time = xfer_parms->use_types; - if (use_types_this_time) { + use_view_this_time = xfer_parms->use_view; + if (use_view_this_time) { /* prepare for a full-blown xfer using btype, ftype, and disp */ buf_type = xfer_parms->btype; file_type = xfer_parms->ftype; @@ -1563,20 +1559,16 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, * Don't bother to reset the view if we're not using the types this time, * and did we didn't use them last time either. */ - used_types_last_time = file->old_use_types; - if (used_types_last_time || /* change to new ftype or MPI_BYTE */ - use_types_this_time) { /* almost certainly a different ftype */ + used_view_last_time = file->old_use_view; + if (used_view_last_time || /* change to new ftype or MPI_BYTE */ + use_view_this_time) { /* almost certainly a different ftype */ /*OKAY: CAST DISCARDS CONST QUALIFIER*/ if (MPI_SUCCESS != MPI_File_set_view(file->f, mpi_disp, MPI_BYTE, file_type, (char*)"native", file->info)) HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_File_set_view failed"); } - /* - * We always set the use_types flag to 0 because the default is not to - * use types next time, unless someone explicitly requests it by setting - * this flag to !=0. - */ - file->old_use_types = use_types_this_time; + /* Keep the 'use view' flag around for the next I/O */ + file->old_use_view = use_view_this_time; /* Only p<round> will do the actual write if all procs in comm write same data */ if ((type!=H5FD_MEM_DRAW) && H5_mpi_1_metawrite_g) { @@ -1618,7 +1610,7 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, /* Calling MPI_Get_count with "MPI_BYTE" is only valid when we actually * had the 'buf_type' set to MPI_BYTE -QAK */ - if(use_types_this_time) { + if(use_view_this_time) { /* Figure out the mapping from the MPI 'buf_type' to bytes, someday... * If this gets fixed (and MPI_Get_count() is reliable), the * kludge below where the 'bytes_written' value from MPI_Get_count() is diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h index 3c11706..32dccce 100644 --- a/src/H5FDmpio.h +++ b/src/H5FDmpio.h @@ -70,7 +70,8 @@ __DLL__ herr_t H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode); __DLL__ herr_t H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode/*out*/); __DLL__ htri_t H5FD_mpio_tas_allsame(H5FD_t *_file, hbool_t newval); __DLL__ MPI_Comm H5FD_mpio_communicator(H5FD_t *_file); -__DLL__ herr_t H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, MPI_Datatype ftype); +__DLL__ herr_t H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, + MPI_Datatype ftype, unsigned use_view); __DLL__ herr_t H5FD_mpio_teardown(hid_t dxpl_id); __DLL__ herr_t H5FD_mpio_wait_for_left_neighbor(H5FD_t *file); __DLL__ herr_t H5FD_mpio_signal_right_neighbor(H5FD_t *file); diff --git a/src/H5Smpio.c b/src/H5Smpio.c index f1a725c..f09a129 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -27,9 +27,8 @@ #include "H5private.h" #include "H5Eprivate.h" #include "H5Fpkg.h" /* Ugly, but necessary for the MPIO I/O accesses */ -#include "H5Spkg.h" - #include "H5FDmpio.h" /*the MPIO file driver */ +#include "H5Spkg.h" #ifndef H5_HAVE_PARALLEL /* @@ -53,24 +52,36 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ); static herr_t H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, + hbool_t *is_derived_type ); +static herr_t +H5S_mpio_hyper_contig_type( const H5S_t *space, const size_t elmt_size, + /* out: */ + MPI_Datatype *new_type, + hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ); static herr_t H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ); static herr_t H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t UNUSED *pline, - const struct H5O_fill_t UNUSED *fill, - const struct H5O_efl_t UNUSED *efl, size_t elmt_size, + size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/, const hbool_t do_write); @@ -85,12 +96,17 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection * (useful if this is the buffer type for xfer) + * *extra_offset Number of bytes of offset within dataset + * *use_view 0 if view not needed, 1 if needed * *is_derived_type 0 if MPI primitive type, 1 if derived * * Programmer: rky 980813 * * Modifications: * + * Quincey Koziol, June 18, 2002 + * Added 'extra_offset' and 'use_view' parameters + * *------------------------------------------------------------------------- */ herr_t @@ -98,6 +114,8 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ) { hsize_t total_bytes; @@ -110,13 +128,14 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size, /* Just treat the entire extent as a block of bytes */ total_bytes = (hsize_t)elmt_size; - for (i=0; i<space->extent.u.simple.rank; ++i) { + for (i=0; i<space->extent.u.simple.rank; ++i) total_bytes *= space->extent.u.simple.size[i]; - } /* fill in the return values */ *new_type = MPI_BYTE; - *count = (size_t)total_bytes; + *count=total_bytes; + *extra_offset = 0; + *use_view = 0; *is_derived_type = 0; #ifdef H5Smpi_DEBUG @@ -147,6 +166,10 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size, * akc, rky 2000-11-16 Replaced hard coded dimension size with * H5S_MAX_RANK. * + * Quincey Koziol, June 18, 2002 + * Added 'extra_offset' and 'use_view' parameters. Also accomodate + * selection offset in MPI type built. + * *------------------------------------------------------------------------- */ herr_t @@ -154,6 +177,8 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ) { struct dim { /* less hassle than malloc/free & ilk */ @@ -188,7 +213,7 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, /* make a local copy of the dimension info so we can transform them */ assert(rank<=H5S_MAX_RANK); /* within array bounds */ for ( i=0; i<rank; ++i) { - d[i].start = diminfo[i].start; + d[i].start = diminfo[i].start+space->select.offset[i]; d[i].strid = diminfo[i].stride; d[i].block = diminfo[i].block; d[i].count = diminfo[i].count; @@ -433,6 +458,8 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, /* fill in the remaining return values */ *count = 1; /* only have to move one of these suckers! */ + *extra_offset = 0; + *use_view = 1; *is_derived_type = 1; goto done; @@ -440,6 +467,8 @@ empty: /* special case: empty hyperslab */ *new_type = MPI_BYTE; *count = 0; + *extra_offset = 0; + *use_view = 1; /* Note that this 'use_view' could go either way, but go with '1' for now */ *is_derived_type = 0; done: @@ -452,6 +481,87 @@ done: /*------------------------------------------------------------------------- + * Function: H5S_mpio_hyper_contig_type + * + * Purpose: Translate a contiguous HDF5 "hyperslab" selection into an MPI type. + * + * Return: non-negative on success, negative on failure. + * + * Outputs: *new_type the MPI type corresponding to the selection + * *count how many objects of the new_type in selection + * (useful if this is the buffer type for xfer) + * *extra_offset Number of bytes of offset within dataset + * *use_view 0 if view not needed, 1 if needed + * *is_derived_type 0 if MPI primitive type, 1 if derived + * + * Programmer: Quincey Koziol, 2002/06/17 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_mpio_hyper_contig_type( const H5S_t *space, const size_t elmt_size, + /* out: */ + MPI_Datatype *new_type, + hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, + hbool_t *is_derived_type ) +{ + hsize_t total_bytes; /* Number of bytes in selection */ + hssize_t nelem; /* Number of elements in selection */ + hsize_t byte_offset; /* Byte offset of contiguous region within selection */ + hsize_t acc; /* Accumulator */ + hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset in selection */ + int ndims; /* Number of dimensions of dataset */ + int i; /* Local index */ + + FUNC_ENTER(H5S_mpio_hyper_contig_type, FAIL); + + /* Check args */ + assert (space); + + /* Get the number of elements in the selection */ + nelem=H5S_get_select_npoints(space); + + /* Compute the number of bytes in selection */ + total_bytes = (hsize_t)elmt_size*nelem; + + /* Set up convenient aliased */ + ndims=space->extent.u.simple.rank; + + /* Initialize row sizes for each dimension */ + for(i=(ndims-1),acc=1; i>=0; i--) { + slab[i]=acc*elmt_size; + acc*=space->extent.u.simple.size[i]; + } /* end for */ + + /* Add in the selection offset */ + assert(space->select.sel_info.hslab.diminfo); + for(i=0; i<ndims; i++) + offset[i] = space->select.sel_info.hslab.diminfo[i].start+space->select.offset[i]; + + /* Compute the initial buffer offset */ + for(i=0,byte_offset=0; i<ndims; i++) + byte_offset+=offset[i]*slab[i]; + + /* fill in the return values */ + *new_type = MPI_BYTE; + *count=total_bytes; + *extra_offset = byte_offset; + *use_view = 0; + *is_derived_type = 0; + +#ifdef H5Smpi_DEBUG + HDfprintf(stdout, "Leave %s total_bytes=%Hu\n", FUNC, total_bytes ); +#endif + FUNC_LEAVE (SUCCEED); +} /* end H5S_mpio_hyper_contig_type() */ + + +/*------------------------------------------------------------------------- * Function: H5S_mpio_space_type * * Purpose: Translate an HDF5 dataspace selection into an MPI type. @@ -462,12 +572,17 @@ done: * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection * (useful if this is the buffer type for xfer) + * *extra_offset Number of bytes of offset within dataset + * *use_view 0 if view not needed, 1 if needed * *is_derived_type 0 if MPI primitive type, 1 if derived * * Programmer: rky 980813 * * Modifications: * + * Quincey Koziol, June 18, 2002 + * Added 'extra_offset' and 'use_view' parameters + * *------------------------------------------------------------------------- */ herr_t @@ -475,6 +590,8 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, /* out: */ MPI_Datatype *new_type, hsize_t *count, + hsize_t *extra_offset, + hbool_t *use_view, hbool_t *is_derived_type ) { int err; @@ -497,10 +614,9 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, case H5S_SEL_NONE: case H5S_SEL_ALL: err = H5S_mpio_all_type( space, elmt_size, - /* out: */ new_type, count, is_derived_type ); - if (err<0) { + /* out: */ new_type, count, extra_offset, use_view, is_derived_type ); + if (err<0) HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type"); - } break; case H5S_SEL_POINTS: @@ -509,11 +625,16 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, break; case H5S_SEL_HYPERSLABS: - err = H5S_mpio_hyper_type( space, elmt_size, - /* out: */ new_type, count, is_derived_type ); - if (err) { + if(H5S_select_contiguous(space)) { + err = H5S_mpio_hyper_contig_type( space, elmt_size, + /* out: */ new_type, count, extra_offset, use_view, is_derived_type ); + } /* end if */ + else { + err = H5S_mpio_hyper_type( space, elmt_size, + /* out: */ new_type, count, extra_offset, use_view, is_derived_type ); + } /* end else */ + if (err<0) HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type"); - } break; default: @@ -561,27 +682,33 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, * Removed 'disp' parameter from H5FD_mpio_setup routine and use the * address of the dataset in MPI_File_set_view() calls, as necessary. * + * QAK - 2002/06/18 + * Removed 'pline', 'fill' & 'efl' parameters, since they were not + * used. Also, switch to getting the 'use_view' and 'extra_offset' + * settings for each selection. + * *------------------------------------------------------------------------- */ herr_t H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t UNUSED *pline, - const struct H5O_fill_t UNUSED *fill, - const struct H5O_efl_t UNUSED *efl, size_t elmt_size, + size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - hid_t dxpl_id, void *buf /*out*/, + hid_t dxpl_id, void *_buf /*out*/, hbool_t *must_convert /*out*/, const hbool_t do_write ) { - herr_t ret_value = SUCCEED; - int err; - haddr_t addr; - hsize_t mpi_count; - hsize_t mpi_buf_count, mpi_unused_count; - MPI_Datatype mpi_buf_type, mpi_file_type; - hbool_t mbt_is_derived=0, - mft_is_derived=0; + haddr_t addr; /* Address of dataset (or selection) within file */ + hsize_t mpi_buf_count, mpi_file_count; /* Number of "objects" to transfer */ + hsize_t mpi_buf_offset, mpi_file_offset; /* Offset within dataset where selection (ie. MPI type) begins */ + MPI_Datatype mpi_buf_type, mpi_file_type; /* MPI types for buffer (memory) and file */ + hbool_t mbt_use_view=0, /* Whether we need to use a view for the buffer (memory) type */ + mft_use_view=0; /* Whether we need to use a view for the file type */ + hbool_t mbt_is_derived=0, /* Whether the buffer (memory) type is derived and needs to be free'd */ + mft_is_derived=0; /* Whether the file type is derived and needs to be free'd */ hbool_t plist_is_setup=0; /* Whether the dxpl has been customized */ + uint8_t *buf=(uint8_t *)_buf; /* Alias for pointer arithmetic */ + int err; /* Error detection value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER (H5S_mpio_spaces_xfer, FAIL); @@ -640,6 +767,8 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, /* out: */ &mpi_buf_type, &mpi_buf_count, + &mpi_buf_offset, + &mbt_use_view, &mbt_is_derived ); if (MPI_SUCCESS != err) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI buf type"); @@ -648,7 +777,9 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, err = H5S_mpio_space_type( file_space, elmt_size, /* out: */ &mpi_file_type, - &mpi_unused_count, + &mpi_file_count, + &mpi_file_offset, + &mft_use_view, &mft_is_derived ); if (MPI_SUCCESS != err) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI file type"); @@ -657,7 +788,7 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, * the address to read from. This should be used as the diplacement for * a call to MPI_File_set_view() in the read or write call. */ - addr = f->shared->base_addr + layout->addr; + addr = f->shared->base_addr + layout->addr + mpi_file_offset; #ifdef H5Smpi_DEBUG HDfprintf(stdout, "spaces_xfer: addr=%a\n", addr ); #endif @@ -666,26 +797,22 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, * Pass buf type, file type to the file driver. Request an MPI type * transfer (instead of an elementary byteblock transfer). */ - if(H5FD_mpio_setup(dxpl_id, mpi_buf_type, mpi_file_type)<0) + if(H5FD_mpio_setup(dxpl_id, mpi_buf_type, mpi_file_type, (unsigned)(mbt_use_view || mft_use_view))<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O type properties0"); plist_is_setup=1; + /* Adjust the buffer pointer to the beginning of the selection */ + buf+=mpi_buf_offset; + /* transfer the data */ - mpi_count = (size_t)mpi_buf_count; - if (mpi_count != mpi_buf_count) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "transfer size overflows size_t"); - } if (do_write) { - err = H5FD_write(f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, mpi_count, buf); - if (err) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed"); - } + err = H5FD_write(f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, mpi_buf_count, buf); + if (err<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed"); } else { - err = H5FD_read (f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, mpi_count, buf); - if (err) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed"); - } + err = H5FD_read (f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, mpi_buf_count, buf); + if (err<0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed"); } done: @@ -698,17 +825,13 @@ done: /* free the MPI buf and file types */ if (mbt_is_derived) { err = MPI_Type_free( &mpi_buf_type ); - if (MPI_SUCCESS != err) { - HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, - "unable to free MPI file type"); - } + if (MPI_SUCCESS != err) + HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, "unable to free MPI file type"); } if (mft_is_derived) { err = MPI_Type_free( &mpi_file_type ); - if (MPI_SUCCESS != err) { - HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, - "unable to free MPI file type"); - } + if (MPI_SUCCESS != err) + HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, "unable to free MPI file type"); } FUNC_LEAVE (ret_value); @@ -733,9 +856,9 @@ done: */ herr_t H5S_mpio_spaces_read(H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, - const struct H5O_fill_t *fill, - const struct H5O_efl_t *efl, size_t elmt_size, + const struct H5O_pline_t UNUSED *pline, + const struct H5O_fill_t UNUSED *fill, + const struct H5O_efl_t UNUSED *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/) @@ -744,7 +867,7 @@ H5S_mpio_spaces_read(H5F_t *f, const struct H5O_layout_t *layout, FUNC_ENTER (H5S_mpio_spaces_read, FAIL); - ret_value = H5S_mpio_spaces_xfer(f, layout, pline, fill, efl, elmt_size, + ret_value = H5S_mpio_spaces_xfer(f, layout, elmt_size, file_space, mem_space, dxpl_id, buf, must_convert/*out*/, 0/*read*/); @@ -770,9 +893,9 @@ H5S_mpio_spaces_read(H5F_t *f, const struct H5O_layout_t *layout, */ herr_t H5S_mpio_spaces_write(H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, - const struct H5O_fill_t *fill, - const struct H5O_efl_t *efl, size_t elmt_size, + const struct H5O_pline_t UNUSED *pline, + const struct H5O_fill_t UNUSED *fill, + const struct H5O_efl_t UNUSED *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id, const void *buf, hbool_t *must_convert/*out*/) @@ -781,7 +904,8 @@ H5S_mpio_spaces_write(H5F_t *f, const struct H5O_layout_t *layout, FUNC_ENTER (H5S_mpio_spaces_write, FAIL); - ret_value = H5S_mpio_spaces_xfer(f, layout, pline, fill, efl, elmt_size, + /*OKAY: CAST DISCARDS CONST QUALIFIER*/ + ret_value = H5S_mpio_spaces_xfer(f, layout, elmt_size, file_space, mem_space, dxpl_id, (void*)buf, must_convert/*out*/, 1/*write*/); |