summaryrefslogtreecommitdiffstats
path: root/src/H5Smpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Smpio.c')
-rw-r--r--src/H5Smpio.c244
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*/);