summaryrefslogtreecommitdiffstats
path: root/src/H5Dmpio.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-12-29 14:32:06 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-12-29 14:32:06 (GMT)
commit37232bd4f0f8199f956c823cdff72ece2ca9aa16 (patch)
tree38e37f7208355500b7f223e90bf014424c63300b /src/H5Dmpio.c
parent20146575aaeead9e05af73977dee863de63bf50f (diff)
downloadhdf5-37232bd4f0f8199f956c823cdff72ece2ca9aa16.zip
hdf5-37232bd4f0f8199f956c823cdff72ece2ca9aa16.tar.gz
hdf5-37232bd4f0f8199f956c823cdff72ece2ca9aa16.tar.bz2
[svn-r9729] Purpose:
Bug Fix/Code Cleanup/Doc Cleanup/Optimization/Branch Sync :-) Description: Generally speaking, this is the "signed->unsigned" change to selections. However, in the process of merging code back, things got stickier and stickier until I ended up doing a big "sync the two branches up" operation. So... I brought back all the "infrastructure" fixes from the development branch to the release branch (which I think were actually making some improvement in performance) as well as fixed several bugs which had been fixed in one branch, but not the other. I've also tagged the repository before making this checkin with the label "before_signed_unsigned_changes". Platforms tested: FreeBSD 4.10 (sleipnir) w/parallel & fphdf5 FreeBSD 4.10 (sleipnir) w/threadsafe FreeBSD 4.10 (sleipnir) w/backward compatibility Solaris 2.7 (arabica) w/"purify options" Solaris 2.8 (sol) w/FORTRAN & C++ AIX 5.x (copper) w/parallel & FORTRAN IRIX64 6.5 (modi4) w/FORTRAN Linux 2.4 (heping) w/FORTRAN & C++ Misc. update:
Diffstat (limited to 'src/H5Dmpio.c')
-rw-r--r--src/H5Dmpio.c228
1 files changed, 218 insertions, 10 deletions
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index b96d32e..9d1f65c 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -39,16 +39,18 @@
#ifdef H5_HAVE_PARALLEL
-/* Interface initialization */
-#define INTERFACE_INIT NULL
-static int interface_initialize_g = 0;
-
static herr_t
H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space,
void *buf/*out*/,
hbool_t do_write);
+
+static herr_t
+H5D_mpio_spaces_span_xfer(H5D_io_info_t *io_info, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space,
+ void *buf/*out*/,
+ hbool_t do_write);
/*-------------------------------------------------------------------------
* Function: H5D_mpio_opt_possible
@@ -89,13 +91,14 @@ H5D_mpio_opt_possible( const H5D_t *dset, const H5S_t *mem_space, const H5S_t *f
HGOTO_DONE(FALSE);
/* Check whether both selections are "regular" */
+#ifndef KYANG
c1=H5S_SELECT_IS_REGULAR(file_space);
c2=H5S_SELECT_IS_REGULAR(mem_space);
if(c1==FAIL || c2==FAIL)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid check for single selection blocks");
if(c1==FALSE || c2==FALSE)
HGOTO_DONE(FALSE);
-
+#endif
/* Can't currently handle point selections */
if (H5S_SEL_POINTS==H5S_GET_SELECT_TYPE(mem_space) || H5S_SEL_POINTS==H5S_GET_SELECT_TYPE(file_space))
HGOTO_DONE(FALSE);
@@ -107,7 +110,7 @@ H5D_mpio_opt_possible( const H5D_t *dset, const H5S_t *mem_space, const H5S_t *f
if ((flags&H5S_CONV_STORAGE_MASK)==H5S_CONV_STORAGE_CHUNKED) {
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Chunk dimensions */
- hssize_t startf[H5S_MAX_RANK], /* Selection start bounds */
+ hsize_t startf[H5S_MAX_RANK], /* Selection start bounds */
endf[H5S_MAX_RANK]; /* Selection end bounds */
unsigned dim_rankf; /* Number of dimensions of file dataspace */
int pcheck_hyper,check_hyper, /* Flags for checking if selection is in one chunk */
@@ -368,6 +371,129 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_mpio_spaces_xfer() */
+
+/** The following function has been tested, don't call this
+ function until you don't see this line. Nov. 11,2004, KY**/
+
+static herr_t
+H5D_mpio_spaces_span_xfer(H5D_io_info_t *io_info, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space,
+ void *_buf /*out*/, hbool_t do_write )
+{
+ haddr_t addr; /* Address of dataset (or selection) within file */
+ size_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_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 mpi_code; /* MPI return code */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_mpio_spaces_span_xfer);
+
+ /* Check args */
+ assert (io_info);
+ assert (io_info->dset);
+ assert (file_space);
+ assert (mem_space);
+ assert (buf);
+ assert (IS_H5FD_MPIO(io_info->dset->ent.file));
+ /* Make certain we have the correct type of property list */
+ assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
+
+ printf("coming to span tree xfer \n");
+ /* create the MPI buffer type */
+ if(H5S_SELECT_IS_REGULAR(mem_space)==TRUE){
+ if (H5S_mpio_space_type( mem_space, elmt_size,
+ /* out: */
+ &mpi_buf_type,
+ &mpi_buf_count,
+ &mpi_buf_offset,
+ &mbt_is_derived )<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI buf type");}
+ else {
+ if (H5S_mpio_space_span_type( mem_space, elmt_size,
+ /* out: */
+ &mpi_buf_type,
+ &mpi_buf_count,
+ &mpi_buf_offset,
+ &mbt_is_derived )<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI buf type");
+ }
+ printf("mpi_buf_count %d\n",mpi_buf_count);
+ /* create the MPI file type */
+
+ if(H5S_SELECT_IS_REGULAR(file_space)== TRUE){
+ if ( H5S_mpio_space_type( file_space, elmt_size,
+ /* out: */
+ &mpi_file_type,
+ &mpi_file_count,
+ &mpi_file_offset,
+ &mft_is_derived )<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI file type");
+ }
+ else {
+ if ( H5S_mpio_space_span_type( file_space, elmt_size,
+ /* out: */
+ &mpi_file_type,
+ &mpi_file_count,
+ &mpi_file_offset,
+ &mft_is_derived )<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI file type");
+ }
+ /* Get the base address of the contiguous dataset or the chunk */
+ if(io_info->dset->shared->layout.type == H5D_CONTIGUOUS)
+ addr = H5D_contig_get_addr(io_info->dset) + mpi_file_offset;
+ else {
+ haddr_t chunk_addr; /* for collective chunk IO */
+
+ assert(io_info->dset->shared->layout.type == H5D_CHUNKED);
+ chunk_addr=H5D_istore_get_addr(io_info,NULL);
+ addr = H5F_BASE_ADDR(io_info->dset->ent.file) + chunk_addr + mpi_file_offset;
+ }
+
+ /*
+ * Pass buf type, file type to the file driver. Request an MPI type
+ * transfer (instead of an elementary byteblock transfer).
+ */
+ if(H5FD_mpi_setup_collective(io_info->dxpl_id, mpi_buf_type, mpi_file_type)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties");
+ plist_is_setup=1;
+
+ /* Adjust the buffer pointer to the beginning of the selection */
+ buf+=mpi_buf_offset;
+
+ /* transfer the data */
+ if (do_write) {
+ if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed");
+ } else {
+ if (H5F_block_read (io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed");
+ }
+
+done:
+ /* Reset the dxpl settings */
+ if(plist_is_setup) {
+ if(H5FD_mpi_teardown_collective(io_info->dxpl_id)<0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to reset dxpl values");
+ } /* end if */
+
+ /* free the MPI buf and file types */
+ if (mbt_is_derived) {
+ if (MPI_SUCCESS != (mpi_code= MPI_Type_free( &mpi_buf_type )))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
+ }
+ if (mft_is_derived) {
+ if (MPI_SUCCESS != (mpi_code= MPI_Type_free( &mpi_file_type )))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_mpio_spaces_span_xfer() */
+
/*-------------------------------------------------------------------------
* Function: H5D_mpio_spaces_read
@@ -397,12 +523,11 @@ H5D_mpio_spaces_read(H5D_io_info_t *io_info,
{
herr_t ret_value;
- FUNC_ENTER_NOAPI(H5D_mpio_spaces_read, FAIL);
+ FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_spaces_read);
ret_value = H5D_mpio_spaces_xfer(io_info, elmt_size, file_space,
mem_space, buf, 0/*read*/);
-done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_mpio_spaces_read() */
@@ -435,14 +560,97 @@ H5D_mpio_spaces_write(H5D_io_info_t *io_info,
{
herr_t ret_value;
- FUNC_ENTER_NOAPI(H5D_mpio_spaces_write, FAIL);
+ FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_spaces_write);
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
ret_value = H5D_mpio_spaces_xfer(io_info, elmt_size, file_space,
mem_space, (void*)buf, 1/*write*/);
-done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_mpio_spaces_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_mpio_spaces_span_read
+ *
+ * Purpose: MPI-IO function to read directly from app buffer to file for
+ span-tree
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: KY
+ * Note : Don't call this routine
+ * until you don't see this line. 11/11/2004, KY
+ *
+ * Modifications:
+ *
+ * rky 980918
+ * Added must_convert parameter to let caller know we can't optimize the xfer.
+ *
+ * QAK - 2002/04/02
+ * Removed the must_convert parameter and move preconditions to
+ * H5S_mpio_opt_possible() routine
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_mpio_spaces_span_read(H5D_io_info_t *io_info,
+ size_t UNUSED nelmts, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space,
+ void *buf/*out*/)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_spaces_span_read);
+
+ ret_value = H5D_mpio_spaces_span_xfer(io_info, elmt_size, file_space,
+ mem_space, buf, 0/*read*/);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_mpio_spaces_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_mpio_spaces_span_write
+ *
+ * Purpose: MPI-IO function to write directly from app buffer to file.
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: KY
+ * Note: Don't call this funtion until you don't see this line.
+ * KY, 11/11/04
+
+ *
+ * Modifications:
+ *
+ * rky 980918
+ * Added must_convert parameter to let caller know we can't optimize the xfer.
+ *
+ * QAK - 2002/04/02
+ * Removed the must_convert parameter and move preconditions to
+ * H5S_mpio_opt_possible() routine
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_mpio_spaces_span_write(H5D_io_info_t *io_info,
+ size_t UNUSED nelmts, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space,
+ const void *buf)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_spaces_span_write);
+
+ printf(" coming to spaces_span_write function\n");
+ fflush(stdout);
+ /*OKAY: CAST DISCARDS CONST QUALIFIER*/
+ printf("element size %d\n",elmt_size);
+ ret_value = H5D_mpio_spaces_span_xfer(io_info, elmt_size, file_space,
+ mem_space, (void*)buf, 1/*write*/);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_mpio_spaces_span_write() */
#endif /* H5_HAVE_PARALLEL */