diff options
Diffstat (limited to 'src/H5Smpio.c')
-rw-r--r-- | src/H5Smpio.c | 244 |
1 files changed, 184 insertions, 60 deletions
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*/); |