diff options
Diffstat (limited to 'src/H5Dio.c')
-rw-r--r-- | src/H5Dio.c | 479 |
1 files changed, 342 insertions, 137 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 95c4c37..fbbf4dc 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -70,6 +70,8 @@ typedef struct fm_map { } fm_map; /* Local functions */ +static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, + const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id); static herr_t H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, void *buf/*out*/); @@ -77,24 +79,24 @@ static herr_t H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, const void *buf); static herr_t -H5D_contig_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, +H5D_contig_read(H5D_io_info_t *io_info, hsize_t nelmts, + const H5T_t *mem_type, const H5S_t *mem_space, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, void *buf/*out*/); static herr_t -H5D_contig_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, +H5D_contig_write(H5D_io_info_t *io_info, hsize_t nelmts, + const H5T_t *mem_type, const H5S_t *mem_space, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, const void *buf); static herr_t -H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, +H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, + const H5T_t *mem_type, const H5S_t *mem_space, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, void *buf/*out*/); static herr_t -H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, +H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, + const H5T_t *mem_type, const H5S_t *mem_space, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, const void *buf); #ifdef H5_HAVE_PARALLEL static herr_t @@ -102,7 +104,19 @@ H5D_io_assist_mpio(hid_t dxpl_id, H5D_dxpl_cache_t *dxpl_cache, hbool_t *xfer_mode_changed); static herr_t H5D_io_restore_mpio(hid_t dxpl_id); -#endif /*H5_HAVE_PARALLEL*/ +static htri_t +H5D_get_collective_io_consensus(const H5F_t *file, + const htri_t local_opinion, + const unsigned flags); +#endif /* H5_HAVE_PARALLEL */ + +/* I/O info operations */ +static herr_t +H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *mem_space, const H5S_t *file_space, + unsigned flags, hbool_t *use_par_opt_io, H5D_io_info_t *io_info); + +/* Chunk operations */ static herr_t H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_space, const H5S_t *mem_space, fm_map *fm); static herr_t H5D_destroy_chunk_map(const fm_map *fm); @@ -113,9 +127,6 @@ static herr_t H5D_chunk_file_cb(void *elem, hid_t type_id, hsize_t ndims, hssize_t *coords, void *fm); static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, hsize_t ndims, hssize_t *coords, void *fm); -static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, - const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id); - /* Declare a free list to manage blocks of single datatype element data */ H5FL_BLK_DEFINE(type_elem); @@ -639,12 +650,14 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, hsize_t nelmts; /*total number of elmts */ H5T_path_t *tpath = NULL; /*type conversion info */ const H5T_t *mem_type = NULL; /* Memory datatype */ - H5S_conv_t *sconv=NULL; /*space conversion funcs*/ + H5D_io_info_t io_info; /* Dataset I/O info */ hbool_t use_par_opt_io=FALSE; /* Whether the 'optimized' I/O routines with be parallel */ #ifdef H5_HAVE_PARALLEL hbool_t xfer_mode_changed=FALSE; /* Whether the transfer mode was changed */ +#ifdef H5_HAVE_INSTRUMENTED_LIBRARY int prop_value,new_value; htri_t check_prop; +#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ #endif /*H5_HAVE_PARALLEL*/ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */ @@ -756,9 +769,9 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, assert(0 && "Unhandled layout type!"); } /* end switch */ - /* Get dataspace functions */ - if (NULL==(sconv=H5S_find(dataset->ent.file, mem_space, file_space, sconv_flags, &use_par_opt_io, &dataset->shared->layout))) - HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from file to memory data space") + /* Set up I/O operation */ + if(H5D_ioinfo_init(dataset,dxpl_cache,dxpl_id,mem_space,file_space,sconv_flags,&use_par_opt_io,&io_info)<0) + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation") #ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_INSTRUMENTED_LIBRARY @@ -791,13 +804,13 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, /* Determine correct I/O routine to invoke */ if(dataset->shared->layout.type!=H5D_CHUNKED) { - if(H5D_contig_read(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, - dxpl_cache, dxpl_id, dataset->shared->type_id, mem_type_id, buf)<0) + if(H5D_contig_read(&io_info, nelmts, mem_type, mem_space, file_space, tpath, + dataset->shared->type_id, mem_type_id, buf)<0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") } /* end if */ else { - if(H5D_chunk_read(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, - dxpl_cache, dxpl_id, dataset->shared->type_id, mem_type_id, buf)<0) + if(H5D_chunk_read(&io_info, nelmts, mem_type, mem_space, file_space, tpath, + dataset->shared->type_id, mem_type_id, buf)<0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") } /* end else */ @@ -866,12 +879,14 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, hsize_t nelmts; /*total number of elmts */ H5T_path_t *tpath = NULL; /*type conversion info */ const H5T_t *mem_type = NULL; /* Memory datatype */ - H5S_conv_t *sconv=NULL; /*space conversion funcs*/ + H5D_io_info_t io_info; /* Dataset I/O info */ hbool_t use_par_opt_io=FALSE; /* Whether the 'optimized' I/O routines with be parallel */ #ifdef H5_HAVE_PARALLEL hbool_t xfer_mode_changed=FALSE; /* Whether the transfer mode was changed */ +#ifdef H5_HAVE_INSTRUMENTED_LIBRARY int prop_value,new_value; htri_t check_prop; +#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ #endif /*H5_HAVE_PARALLEL*/ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */ @@ -1003,9 +1018,9 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, assert(0 && "Unhandled layout type!"); } /* end switch */ - /* Get dataspace functions */ - if (NULL==(sconv=H5S_find(dataset->ent.file, mem_space, file_space, sconv_flags, &use_par_opt_io, &dataset->shared->layout))) - HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from memory to file data space") + /* Set up I/O operation */ + if(H5D_ioinfo_init(dataset,dxpl_cache,dxpl_id,mem_space,file_space,sconv_flags,&use_par_opt_io,&io_info)<0) + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation") #ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_INSTRUMENTED_LIBRARY @@ -1014,20 +1029,20 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, a more general collective chunk IO algorithm is applied. */ - if(dataset->shared->layout.type == H5D_CHUNKED) { /*only check for chunking storage */ + if(dataset->shared->layout.type == H5D_CHUNKED) { /*only check for chunking storage */ - check_prop = H5Pexist(dxpl_id,H5D_XFER_COLL_CHUNK_NAME); - if(check_prop < 0) - HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to check property list"); - if(check_prop > 0) { - if(H5Pget(dxpl_id,H5D_XFER_COLL_CHUNK_NAME,&prop_value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to get property value"); - if(!use_par_opt_io) { - new_value = 0; - if(H5Pset(dxpl_id,H5D_XFER_COLL_CHUNK_NAME,&new_value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to set property value"); - } - } + check_prop = H5Pexist(dxpl_id,H5D_XFER_COLL_CHUNK_NAME); + if(check_prop < 0) + HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to check property list"); + if(check_prop > 0) { + if(H5Pget(dxpl_id,H5D_XFER_COLL_CHUNK_NAME,&prop_value)<0) + HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to get property value"); + if(!use_par_opt_io) { + new_value = 0; + if(H5Pset(dxpl_id,H5D_XFER_COLL_CHUNK_NAME,&new_value)<0) + HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to set property value"); + } + } } #endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ @@ -1038,13 +1053,13 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, /* Determine correct I/O routine to invoke */ if(dataset->shared->layout.type!=H5D_CHUNKED) { - if(H5D_contig_write(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, - dxpl_cache, dxpl_id, mem_type_id, dataset->shared->type_id, buf)<0) + if(H5D_contig_write(&io_info, nelmts, mem_type, mem_space, file_space, tpath, + mem_type_id, dataset->shared->type_id, buf)<0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") } /* end if */ else { - if(H5D_chunk_write(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, - dxpl_cache, dxpl_id, mem_type_id, dataset->shared->type_id, buf)<0) + if(H5D_chunk_write(&io_info, nelmts, mem_type, mem_space, file_space, tpath, + mem_type_id, dataset->shared->type_id, buf)<0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") } /* end else */ @@ -1093,12 +1108,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_contig_read(hsize_t nelmts, H5D_t *dataset, +H5D_contig_read(H5D_io_info_t *io_info, hsize_t nelmts, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, void *buf/*out*/) { + H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ + const H5D_dxpl_cache_t *dxpl_cache=io_info->dxpl_cache; /* Local pointer to dataset transfer info */ herr_t status; /*function return status*/ #ifdef H5S_DEBUG H5_timer_t timer; @@ -1120,7 +1136,6 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, hsize_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ H5D_storage_t store; /*union of storage info for dataset */ - H5D_io_info_t io_info; /* Dataset I/O info */ herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_contig_read) @@ -1133,8 +1148,8 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, store.contig.dset_size=dataset->shared->layout.u.contig.size; } /* end if */ - /* Construct dataset I/O info */ - H5D_BUILD_IO_INFO(&io_info,dataset,dxpl_cache,dxpl_id,&store); + /* Set dataset storage for I/O info */ + io_info->store=&store; /* * If there is no type conversion then read directly into the @@ -1150,14 +1165,14 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, || dataset->shared->efl.nused>0 || 0 == nelmts || dataset->shared->layout.type==H5D_COMPACT); H5_CHECK_OVERFLOW(nelmts,hsize_t,size_t); - status = (sconv->read)(&io_info, dataset->shared->layout.readvv, + status = (io_info->ops.read)(io_info, (size_t)nelmts, H5T_get_size(dataset->shared->type), file_space, mem_space, buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].read_timer), &timer); - sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->shared->type); - sconv->stats[1].read_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].read_timer), &timer); + io_info->stats->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->shared->type); + io_info->stats->stats[1].read_ncalls++; #endif /* Check return value from optimized read */ @@ -1252,14 +1267,18 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, H5_timer_begin(&timer); #endif /* Sanity check that space is allocated, then read data from it */ - n = H5S_select_fgath(&io_info, dataset->shared->layout.readvv, + assert(((dataset->shared->layout.type==H5D_CONTIGUOUS && H5F_addr_defined(dataset->shared->layout.u.contig.addr)) + || (dataset->shared->layout.type==H5D_CHUNKED && H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) + || dataset->shared->efl.nused>0 || + dataset->shared->layout.type==H5D_COMPACT); + n = H5D_select_fgath(io_info, file_space, &file_iter, smine_nelmts, tconv_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].gath_timer), &timer); - sconv->stats[1].gath_nbytes += n * src_type_size; - sconv->stats[1].gath_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].gath_timer), &timer); + io_info->stats->stats[1].gath_nbytes += n * src_type_size; + io_info->stats->stats[1].gath_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed") @@ -1268,12 +1287,12 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_mgath(buf, mem_space, &bkg_iter, + n = H5D_select_mgath(buf, mem_space, &bkg_iter, smine_nelmts, dxpl_cache, bkg_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].bkg_timer), &timer); - sconv->stats[1].bkg_nbytes += n * dst_type_size; - sconv->stats[1].bkg_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].bkg_timer), &timer); + io_info->stats->stats[1].bkg_nbytes += n * dst_type_size; + io_info->stats->stats[1].bkg_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed") @@ -1282,7 +1301,7 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, /* * Perform data type conversion. */ - if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0) + if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, io_info->dxpl_id)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed") /* Do the data transform after the conversion (since we're using type mem_type) */ @@ -1296,12 +1315,12 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - status = H5S_select_mscat(tconv_buf, mem_space, + status = H5D_select_mscat(tconv_buf, mem_space, &mem_iter, smine_nelmts, dxpl_cache, buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].scat_timer), &timer); - sconv->stats[1].scat_nbytes += smine_nelmts * dst_type_size; - sconv->stats[1].scat_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].scat_timer), &timer); + io_info->stats->stats[1].scat_nbytes += smine_nelmts * dst_type_size; + io_info->stats->stats[1].scat_ncalls++; #endif if (status<0) HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "scatter failed") @@ -1351,12 +1370,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_contig_write(hsize_t nelmts, H5D_t *dataset, +H5D_contig_write(H5D_io_info_t *io_info, hsize_t nelmts, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, const void *buf) { + H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ + const H5D_dxpl_cache_t *dxpl_cache=io_info->dxpl_cache; /* Local pointer to dataset transfer info */ herr_t status; /*function return status*/ #ifdef H5S_DEBUG H5_timer_t timer; @@ -1378,7 +1398,6 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, hsize_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ H5D_storage_t store; /*union of storage info for dataset */ - H5D_io_info_t io_info; /* Dataset I/O info */ herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_contig_write) @@ -1391,8 +1410,8 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, store.contig.dset_size=dataset->shared->layout.u.contig.size; } /* end if */ - /* Construct dataset I/O info */ - H5D_BUILD_IO_INFO(&io_info,dataset,dxpl_cache,dxpl_id,&store); + /* Set dataset storage for I/O info */ + io_info->store=&store; /* * If there is no type conversion then write directly from the @@ -1403,14 +1422,14 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, H5_timer_begin(&timer); #endif H5_CHECK_OVERFLOW(nelmts,hsize_t,size_t); - status = (sconv->write)(&io_info, dataset->shared->layout.writevv, + status = (io_info->ops.write)(io_info, (size_t)nelmts, H5T_get_size(dataset->shared->type), file_space, mem_space, buf); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].write_timer), &timer); - sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type); - sconv->stats[0].write_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].write_timer), &timer); + io_info->stats->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type); + io_info->stats->stats[0].write_ncalls++; #endif /* Check return value from optimized write */ @@ -1508,12 +1527,12 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_mgath(buf, mem_space, &mem_iter, + n = H5D_select_mgath(buf, mem_space, &mem_iter, smine_nelmts, dxpl_cache, tconv_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].gath_timer), &timer); - sconv->stats[0].gath_nbytes += n * src_type_size; - sconv->stats[0].gath_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].gath_timer), &timer); + io_info->stats->stats[0].gath_nbytes += n * src_type_size; + io_info->stats->stats[0].gath_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed") @@ -1522,14 +1541,14 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_fgath(&io_info, dataset->shared->layout.readvv, + n = H5D_select_fgath(io_info, file_space, &bkg_iter, smine_nelmts, bkg_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].bkg_timer), &timer); - sconv->stats[0].bkg_nbytes += n * dst_type_size; - sconv->stats[0].bkg_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].bkg_timer), &timer); + io_info->stats->stats[0].bkg_nbytes += n * dst_type_size; + io_info->stats->stats[0].bkg_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed") @@ -1538,7 +1557,7 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, /* * Perform data type conversion. */ - if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0) + if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, io_info->dxpl_id)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed") /* Do the data transform after the type conversion (since we're using dataset->shared->type). */ @@ -1552,13 +1571,13 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - status = H5S_select_fscat(&io_info, dataset->shared->layout.writevv, + status = H5D_select_fscat(io_info, file_space, &file_iter, smine_nelmts, tconv_buf); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].scat_timer), &timer); - sconv->stats[0].scat_nbytes += smine_nelmts * dst_type_size; - sconv->stats[0].scat_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].scat_timer), &timer); + io_info->stats->stats[0].scat_nbytes += smine_nelmts * dst_type_size; + io_info->stats->stats[0].scat_ncalls++; #endif if (status<0) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "scatter failed") @@ -1607,12 +1626,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, +H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, void *buf/*out*/) { + H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ + const H5D_dxpl_cache_t *dxpl_cache=io_info->dxpl_cache; /* Local pointer to dataset transfer info */ fm_map fm; /* File<->memory mapping */ H5TB_NODE *chunk_node; /* Current node in chunk TBBT */ herr_t status; /*function return status*/ @@ -1636,7 +1656,6 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, uint8_t *tconv_buf = NULL; /*data type conv buffer */ uint8_t *bkg_buf = NULL; /*background buffer */ H5D_storage_t store; /*union of EFL and chunk pointer in file space */ - H5D_io_info_t io_info; /* Dataset I/O info */ herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_read) @@ -1645,8 +1664,8 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, if(H5D_create_chunk_map(dataset, mem_type, file_space, mem_space, &fm)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't build chunk mapping") - /* Construct dataset I/O info */ - H5D_BUILD_IO_INFO(&io_info,dataset,dxpl_cache,dxpl_id,&store); + /* Set dataset storage for I/O info */ + io_info->store=&store; /* * If there is no type conversion then read directly into the @@ -1677,7 +1696,7 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, store.chunk.index = chunk_info->index; /* Perform the actual read operation */ - status = (sconv->read)(&io_info,dataset->shared->layout.readvv, + status = (io_info->ops.read)(io_info, chunk_info->chunk_points, H5T_get_size(dataset->shared->type), chunk_info->fspace, chunk_info->mspace, buf); @@ -1691,9 +1710,9 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, } /* end while */ #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].read_timer), &timer); - sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->shared->type); - sconv->stats[1].read_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].read_timer), &timer); + io_info->stats->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->shared->type); + io_info->stats->stats[1].read_ncalls++; #endif /* direct xfer accomplished successfully */ @@ -1802,14 +1821,14 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, assert(((dataset->shared->layout.type==H5D_CONTIGUOUS && H5F_addr_defined(dataset->shared->layout.u.contig.addr)) || (dataset->shared->layout.type==H5D_CHUNKED && H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) || dataset->shared->efl.nused>0 || dataset->shared->layout.type==H5D_COMPACT); - n = H5S_select_fgath(&io_info, dataset->shared->layout.readvv, + n = H5D_select_fgath(io_info, chunk_info->fspace, &file_iter, smine_nelmts, tconv_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].gath_timer), &timer); - sconv->stats[1].gath_nbytes += n * src_type_size; - sconv->stats[1].gath_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].gath_timer), &timer); + io_info->stats->stats[1].gath_nbytes += n * src_type_size; + io_info->stats->stats[1].gath_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed") @@ -1818,12 +1837,12 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_mgath(buf, chunk_info->mspace, &bkg_iter, + n = H5D_select_mgath(buf, chunk_info->mspace, &bkg_iter, smine_nelmts, dxpl_cache, bkg_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].bkg_timer), &timer); - sconv->stats[1].bkg_nbytes += n * dst_type_size; - sconv->stats[1].bkg_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].bkg_timer), &timer); + io_info->stats->stats[1].bkg_nbytes += n * dst_type_size; + io_info->stats->stats[1].bkg_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed") @@ -1833,7 +1852,7 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, * Perform data type conversion. */ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, - tconv_buf, bkg_buf, dxpl_id)<0) + tconv_buf, bkg_buf, io_info->dxpl_id)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed") /* Do the data transform after the conversion (since we're using type mem_type) */ @@ -1847,12 +1866,12 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - status = H5S_select_mscat(tconv_buf, chunk_info->mspace, + status = H5D_select_mscat(tconv_buf, chunk_info->mspace, &mem_iter, smine_nelmts, dxpl_cache, buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].scat_timer), &timer); - sconv->stats[1].scat_nbytes += smine_nelmts * dst_type_size; - sconv->stats[1].scat_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].scat_timer), &timer); + io_info->stats->stats[1].scat_nbytes += smine_nelmts * dst_type_size; + io_info->stats->stats[1].scat_ncalls++; #endif if (status<0) HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "scatter failed") @@ -1926,12 +1945,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, +H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, - const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *file_space, H5T_path_t *tpath, hid_t src_id, hid_t dst_id, const void *buf) { + H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ + const H5D_dxpl_cache_t *dxpl_cache=io_info->dxpl_cache; /* Local pointer to dataset transfer info */ fm_map fm; /* File<->memory mapping */ H5TB_NODE *chunk_node; /* Current node in chunk TBBT */ herr_t status; /*function return status*/ @@ -1955,7 +1975,6 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, uint8_t *tconv_buf = NULL; /*data type conv buffer */ uint8_t *bkg_buf = NULL; /*background buffer */ H5D_storage_t store; /*union of EFL and chunk pointer in file space */ - H5D_io_info_t io_info; /* Dataset I/O info */ herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_write) @@ -1964,8 +1983,8 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, if(H5D_create_chunk_map(dataset, mem_type, file_space, mem_space, &fm)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't build chunk mapping") - /* Construct dataset I/O info */ - H5D_BUILD_IO_INFO(&io_info,dataset,dxpl_cache,dxpl_id,&store); + /* Set dataset storage for I/O info */ + io_info->store=&store; /* * If there is no type conversion then write directly from the @@ -1990,7 +2009,7 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, store.chunk.index = chunk_info->index; /* Perform the actual write operation */ - status = (sconv->write)(&io_info, dataset->shared->layout.writevv, + status = (io_info->ops.write)(io_info, chunk_info->chunk_points, H5T_get_size(dataset->shared->type), chunk_info->fspace, chunk_info->mspace, buf); @@ -2004,9 +2023,9 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, } /* end while */ #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].write_timer), &timer); - sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type); - sconv->stats[0].write_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].write_timer), &timer); + io_info->stats->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type); + io_info->stats->stats[0].write_ncalls++; #endif /* direct xfer accomplished successfully */ @@ -2115,13 +2134,13 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_mgath(buf, chunk_info->mspace, &mem_iter, + n = H5D_select_mgath(buf, chunk_info->mspace, &mem_iter, smine_nelmts, dxpl_cache, tconv_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].gath_timer), &timer); - sconv->stats[1].gath_nbytes += n * src_type_size; - sconv->stats[1].gath_ncalls++; + H5_timer_end(&(io_info->stats->stats[1].gath_timer), &timer); + io_info->stats->stats[1].gath_nbytes += n * src_type_size; + io_info->stats->stats[1].gath_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed") @@ -2130,14 +2149,14 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = H5S_select_fgath(&io_info, dataset->shared->layout.readvv, + n = H5D_select_fgath(io_info, chunk_info->fspace, &bkg_iter, smine_nelmts, bkg_buf/*out*/); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].bkg_timer), &timer); - sconv->stats[0].bkg_nbytes += n * dst_type_size; - sconv->stats[0].bkg_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].bkg_timer), &timer); + io_info->stats->stats[0].bkg_nbytes += n * dst_type_size; + io_info->stats->stats[0].bkg_ncalls++; #endif if (n!=smine_nelmts) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed") @@ -2147,7 +2166,7 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, * Perform data type conversion. */ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, - tconv_buf, bkg_buf, dxpl_id)<0) + tconv_buf, bkg_buf, io_info->dxpl_id)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed") /* Do the data transform after the type conversion (since we're using dataset->shared->type) */ @@ -2161,14 +2180,14 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - status = H5S_select_fscat(&io_info, dataset->shared->layout.writevv, + status = H5D_select_fscat(io_info, chunk_info->fspace, &file_iter, smine_nelmts, tconv_buf); #ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[0].scat_timer), &timer); - sconv->stats[0].scat_nbytes += n * dst_type_size; - sconv->stats[0].scat_ncalls++; + H5_timer_end(&(io_info->stats->stats[0].scat_timer), &timer); + io_info->stats->stats[0].scat_nbytes += n * dst_type_size; + io_info->stats->stats[0].scat_ncalls++; #endif if (status<0) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "scatter failed") @@ -3128,3 +3147,189 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, hsize_t ndims, hssize_ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_chunk_mem_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5S_get_collective_io_consensus + * + * Purpose: Compare notes with all other processes involved in this I/O + * and see if all are go for collective I/O. + * + * If all are, return TRUE. + * + * If any process can't manage collective I/O, then collective + * I/O is impossible, and we return FALSE. + * + * If the flags indicate that collective I/O is impossible, + * skip the interprocess communication and just return FALSE. + * + * In any error is detected, return FAIL. + * + * Return: Success: TRUE or FALSE + * + * Failure: FAIL + * + * Programmer: JRM -- 8/30/04 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ + +#ifdef H5_HAVE_PARALLEL +static htri_t +H5D_get_collective_io_consensus(const H5F_t *file, + const htri_t local_opinion, + const unsigned flags) +{ + htri_t ret_value = FAIL; /* will update if successful */ + MPI_Comm comm; + int int_local_opinion; + int consensus; + int mpi_result; + + FUNC_ENTER_NOAPI_NOINIT(H5D_get_collective_io_consensus); + + HDassert ( ( local_opinion == TRUE ) || ( local_opinion == FALSE ) ); + + /* Don't do the interprocess communication unless the Parallel I/O + * conversion flag is set -- there may not be other processes to + * talk to. + */ + if ( ! ( flags & flags&H5S_CONV_PAR_IO_POSSIBLE ) ) { + + HGOTO_DONE(FALSE); + } + + comm = H5F_mpi_get_comm(file); + + if ( comm == MPI_COMM_NULL ) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, \ + "can't retrieve MPI communicator") + + if ( local_opinion == TRUE ) { + + int_local_opinion = 1; + + } else { + + int_local_opinion = 0; + } + + mpi_result = MPI_Allreduce((void *)(&int_local_opinion), + (void *)(&consensus), + 1, + MPI_INT, + MPI_LAND, + comm); + + if ( mpi_result != MPI_SUCCESS ) + HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_result) + + if ( consensus ) { + + ret_value = TRUE; + + } else { + + ret_value = FALSE; + } + +done: + + FUNC_LEAVE_NOAPI(ret_value); + +} /* H5D_get_collective_io_consensus() */ + +#endif /* H5_HAVE_PARALLEL */ + + +/*------------------------------------------------------------------------- + * Function: H5D_chunk_mem_cb + * + * Purpose: Routine for determining correct I/O operations for + * each I/O action. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, September 30, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, + const H5S_t *mem_space, const H5S_t *file_space, + unsigned flags, hbool_t *use_par_opt_io, H5D_io_info_t *io_info) +{ +#ifdef H5_HAVE_PARALLEL + htri_t opt; /* Flag whether a selection is optimizable */ +#endif /* H5_HAVE_PARALLEL */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_ioinfo_init) + + /* check args */ + HDassert(dset); + HDassert(dset->ent.file); + HDassert(mem_space); + HDassert(file_space); + HDassert(use_par_opt_io); + HDassert(io_info); + + /* Set up "normal" I/O fields */ + io_info->dset=dset; + io_info->dxpl_cache=dxpl_cache; + io_info->dxpl_id=dxpl_id; + io_info->store=NULL; /* Set later in I/O routine? */ + + /* Set I/O operations to initial values */ + io_info->ops=dset->shared->io_ops; + +#ifdef H5_HAVE_PARALLEL + /* + * Check if we can set direct MPI-IO read/write functions + */ + opt=H5D_mpio_opt_possible(dset->ent.file,mem_space,file_space,flags,&dset->shared->layout); + if(opt==FAIL) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, "invalid check for direct IO dataspace "); + + opt = H5D_get_collective_io_consensus(dset->ent.file, opt, flags); + + if ( opt == FAIL ) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, \ + "check for collective I/O consensus failed."); + + /* Check if we can use the optimized parallel I/O routines */ + if(opt==TRUE) { + /* Set the pointers to the MPI-specific routines */ + io_info->ops.read = H5D_mpio_spaces_read; + io_info->ops.write = H5D_mpio_spaces_write; + + /* Indicate that the I/O will be parallel */ + *use_par_opt_io=TRUE; + } /* end if */ + else { + /* Indicate that the I/O will _NOT_ be parallel */ + *use_par_opt_io=FALSE; + +#endif /* H5_HAVE_PARALLEL */ + io_info->ops.read = H5D_select_read; + io_info->ops.write = H5D_select_write; +#ifdef H5_HAVE_PARALLEL + } /* end else */ +#endif /* H5_HAVE_PARALLEL */ + +#ifdef H5S_DEBUG + /* Get the information for the I/O statistics */ + if((io_info->stats=H5S_find(mem_space,file_space))==NULL) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "can't set up selection statistics"); +#endif /* H5S_DEBUG */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_ioinfo_init() */ |