From c719c2d3b876a3ac6f0aec7d776d5aaebf5e1fef Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 1 Oct 2004 18:00:55 -0500 Subject: [svn-r9356] Purpose: Bug fix & code cleanup Description: More dataset cleanups to get to a point where we can fix the chunked I/O bug. Also fix a couple of errors in the recent file object resurrection changes which should hopefully address the recent daily test failres (H5T.c) Platforms tested: FreeBSD 4.10 (sleipnir) w/parallel Solaris 2.7 (arabica) h5committest --- MANIFEST | 2 + src/H5D.c | 73 +++--- src/H5Defl.c | 4 + src/H5Dio.c | 471 ++++++++++++++++++++++++++------------ src/H5Dmpio.c | 176 ++++++++++++++- src/H5Dpkg.h | 135 ++++++++++- src/H5Dprivate.h | 59 ----- src/H5Dselect.c | 4 + src/H5Fpkg.h | 17 -- src/H5Fprivate.h | 17 ++ src/H5Oefl.c | 343 +--------------------------- src/H5Oprivate.h | 24 -- src/H5S.c | 260 +++------------------ src/H5Smpio.c | 173 -------------- src/H5Spkg.h | 11 - src/H5Sprivate.h | 59 +---- src/H5Sselect.c | 670 ------------------------------------------------------- src/H5T.c | 42 ++-- src/Makefile.in | 5 +- 19 files changed, 777 insertions(+), 1768 deletions(-) diff --git a/MANIFEST b/MANIFEST index c5bbf37..c4719c8 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1084,12 +1084,14 @@ ./src/H5D.c ./src/H5Dcontig.c ./src/H5Dcompact.c +./src/H5Defl.c ./src/H5Dio.c ./src/H5Distore.c ./src/H5Dmpio.c ./src/H5Dprivate.h ./src/H5Dpublic.h ./src/H5Dpkg.h +./src/H5Dselect.c ./src/H5Dtest.c ./src/H5E.c ./src/H5Eprivate.h diff --git a/src/H5D.c b/src/H5D.c index 87d7491..5b2fccc 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -22,7 +22,7 @@ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5FOprivate.h" /* File objects */ +#include "H5FOprivate.h" /* File objects */ #include "H5HLprivate.h" /* Local heaps */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -1129,10 +1129,10 @@ hid_t H5Dopen(hid_t loc_id, const char *name) { H5D_t *dset; - H5G_entry_t *loc = NULL; /*location holding the dataset */ - H5G_entry_t ent; /*dataset symbol table entry */ - hid_t ret_value; - hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open dataset */ + H5G_entry_t *loc = NULL; /*location holding the dataset */ + H5G_entry_t ent; /*dataset symbol table entry */ + hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */ + hid_t ret_value; FUNC_ENTER_API(H5Dopen, FAIL) H5TRACE2("i","is",loc_id,name); @@ -1149,7 +1149,7 @@ H5Dopen(hid_t loc_id, const char *name) /* Open the dataset */ if ((dset = H5D_open(&ent, dxpl_id))==NULL) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't open dataset") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") /* Register an atom for the dataset */ if((ret_value=H5I_register(H5I_DATASET, dset)) <0) @@ -1571,9 +1571,9 @@ done: static H5D_shared_t * H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type) { - H5P_genplist_t *plist; /* Property list created */ - H5D_shared_t *new_dset = NULL; /* New dataset object */ - H5D_shared_t *ret_value; /* Return value */ + H5P_genplist_t *plist; /* Property list created */ + H5D_shared_t *new_dset = NULL; /* New dataset object */ + H5D_shared_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5D_new, NULL) @@ -2120,9 +2120,8 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &new_dset->shared->efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list") - /* Get the dataset's data storage method */ - if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, &(new_dset->shared->layout.type)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout") + /* Set the dataset's data storage method */ + new_dset->shared->layout.type=dcpl_layout; } /* end if */ /* Check if this dataset is going into a parallel file and set space allocation time */ @@ -2168,16 +2167,16 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space } /* Set the I/O functions for this layout type */ - new_dset->shared->layout.readvv=H5O_efl_readvv; - new_dset->shared->layout.writevv=H5O_efl_writevv; + new_dset->shared->io_ops.readvv=H5D_efl_readvv; + new_dset->shared->io_ops.writevv=H5D_efl_writevv; } /* end if */ else { if (ndims>0 && max_dim[0]>new_dset->shared->layout.unused.dim[0]) HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL, "extendible contiguous non-external dataset") /* Set the I/O functions for this layout type */ - new_dset->shared->layout.readvv=H5D_contig_readvv; - new_dset->shared->layout.writevv=H5D_contig_writevv; + new_dset->shared->io_ops.readvv=H5D_contig_readvv; + new_dset->shared->io_ops.writevv=H5D_contig_writevv; } /* end else */ /* Compute the total size of a chunk */ @@ -2227,8 +2226,8 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space new_dset->shared->layout.u.chunk.size *= new_dset->shared->layout.u.chunk.dim[u]; /* Set the I/O functions for this layout type */ - new_dset->shared->layout.readvv=H5D_istore_readvv; - new_dset->shared->layout.writevv=H5D_istore_writevv; + new_dset->shared->io_ops.readvv=H5D_istore_readvv; + new_dset->shared->io_ops.writevv=H5D_istore_writevv; /* Initialize the chunk cache for the dataset */ if(H5D_istore_init(file,new_dset)<0) @@ -2260,8 +2259,8 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "compact dataset size is bigger than header message maximum size") /* Set the I/O functions for this layout type */ - new_dset->shared->layout.readvv=H5D_compact_readvv; - new_dset->shared->layout.writevv=H5D_compact_writevv; + new_dset->shared->io_ops.readvv=H5D_compact_readvv; + new_dset->shared->io_ops.writevv=H5D_compact_writevv; } /* end case */ break; @@ -2404,13 +2403,13 @@ H5D_open(H5G_entry_t *ent, hid_t dxpl_id) { H5D_shared_t *shared_fo=NULL; H5D_t *dataset=NULL; - H5D_t *ret_value=NULL; /* Return value */ + H5D_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5D_open, NULL) /* check args */ assert (ent); - + /* Check if dataset was already open */ if((shared_fo=H5FO_opened(ent->file,ent->header))==NULL) { @@ -2425,7 +2424,7 @@ H5D_open(H5G_entry_t *ent, hid_t dxpl_id) if(H5FO_insert(ent->file,ent->header,dataset->shared)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects") - dataset->shared->fo_count=1; + dataset->shared->fo_count = 1; } /* end if */ else { shared_fo->fo_count++; @@ -2567,8 +2566,8 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id) } /* end if */ /* Set the I/O functions for this layout type */ - dataset->shared->layout.readvv=H5D_contig_readvv; - dataset->shared->layout.writevv=H5D_contig_writevv; + dataset->shared->io_ops.readvv=H5D_contig_readvv; + dataset->shared->io_ops.writevv=H5D_contig_writevv; break; case H5D_CHUNKED: @@ -2593,14 +2592,14 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id) } /* Set the I/O functions for this layout type */ - dataset->shared->layout.readvv=H5D_istore_readvv; - dataset->shared->layout.writevv=H5D_istore_writevv; + dataset->shared->io_ops.readvv=H5D_istore_readvv; + dataset->shared->io_ops.writevv=H5D_istore_writevv; break; case H5D_COMPACT: /* Set the I/O functions for this layout type */ - dataset->shared->layout.readvv=H5D_compact_readvv; - dataset->shared->layout.writevv=H5D_compact_writevv; + dataset->shared->io_ops.readvv=H5D_compact_readvv; + dataset->shared->io_ops.writevv=H5D_compact_writevv; break; default: @@ -2678,8 +2677,8 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list") /* Override the I/O functions for this layout type */ - dataset->shared->layout.readvv=H5O_efl_readvv; - dataset->shared->layout.writevv=H5O_efl_writevv; + dataset->shared->io_ops.readvv=H5D_efl_readvv; + dataset->shared->io_ops.writevv=H5D_efl_writevv; } /* end if */ } /* end if */ @@ -2753,8 +2752,8 @@ done: herr_t H5D_close(H5D_t *dataset) { - unsigned free_failed=FALSE; - herr_t ret_value=SUCCEED; /* Return value */ + unsigned free_failed=FALSE; + herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_close, FAIL) @@ -2799,7 +2798,7 @@ H5D_close(H5D_t *dataset) /* Free the buffer for the raw data for compact datasets */ dataset->shared->layout.u.compact.buf=H5MM_xfree(dataset->shared->layout.u.compact.buf); break; - + default: assert ("not implemented yet" && 0); #ifdef NDEBUG @@ -2812,7 +2811,7 @@ H5D_close(H5D_t *dataset) * much we can do if one of these fails, so we just continue. */ free_failed=(H5I_dec_ref(dataset->shared->type_id)<0 || H5S_close(dataset->shared->space)<0 || - H5I_dec_ref(dataset->shared->dcpl_id) < 0); + H5I_dec_ref(dataset->shared->dcpl_id) < 0); /* Remove the dataset from the list of opened objects in the file */ if(H5FO_delete(dataset->ent.file, H5AC_dxpl_id, dataset->ent.header)<0) @@ -2839,10 +2838,10 @@ H5D_close(H5D_t *dataset) free_failed=TRUE; } /* end else */ - H5FL_FREE(H5D_t, dataset); + H5FL_FREE(H5D_t,dataset); if (free_failed) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't free the type or creation property list, but the dataset was freed anyway.") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't free the type or creation property list, but the dataset was freed anyway.") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Defl.c b/src/H5Defl.c index ab3e260..474ac2f 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -34,6 +34,10 @@ static herr_t H5D_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf); +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT NULL + /*------------------------------------------------------------------------- * Function: H5D_efl_read diff --git a/src/H5Dio.c b/src/H5Dio.c index 8130c2d..9d5226f 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -74,6 +74,8 @@ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL /* 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*/); @@ -81,24 +83,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 @@ -106,7 +108,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); @@ -117,9 +131,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,7 +650,7 @@ 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 */ @@ -758,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 @@ -793,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 */ @@ -868,7 +879,7 @@ 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 */ @@ -1007,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 @@ -1018,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 */ @@ -1042,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 */ @@ -1095,12 +1106,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; @@ -1122,7 +1134,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) @@ -1135,8 +1146,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 @@ -1152,14 +1163,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 */ @@ -1258,14 +1269,14 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, || (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, 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") @@ -1274,12 +1285,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") @@ -1288,7 +1299,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") /* @@ -1297,12 +1308,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") @@ -1350,12 +1361,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; @@ -1377,7 +1389,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) @@ -1390,8 +1401,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 @@ -1402,14 +1413,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 */ @@ -1507,12 +1518,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") @@ -1521,14 +1532,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") @@ -1537,7 +1548,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") /* @@ -1546,13 +1557,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") @@ -1599,12 +1610,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*/ @@ -1628,7 +1640,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) @@ -1637,8 +1648,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 @@ -1669,7 +1680,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); @@ -1683,9 +1694,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 */ @@ -1794,14 +1805,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") @@ -1810,12 +1821,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") @@ -1825,7 +1836,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") /* @@ -1834,12 +1845,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") @@ -1911,12 +1922,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*/ @@ -1940,7 +1952,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) @@ -1949,8 +1960,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 @@ -1975,7 +1986,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); @@ -1989,9 +2000,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 */ @@ -2100,13 +2111,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") @@ -2115,14 +2126,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") @@ -2132,7 +2143,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") /* @@ -2141,14 +2152,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") @@ -3108,3 +3119,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() */ diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 864215f..37a49ca 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -51,6 +51,179 @@ H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size, /*------------------------------------------------------------------------- + * Function: H5D_mpio_opt_possible + * + * Purpose: Checks if an direct I/O transfer is possible between memory and + * the file. + * + * Return: Success: Non-negative: TRUE or FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, April 3, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5D_mpio_opt_possible( const H5F_t *file, const H5S_t *mem_space, const H5S_t *file_space, const unsigned flags,const H5O_layout_t *layout) +{ + htri_t c1,c2; /* Flags whether a selection is optimizable */ + htri_t ret_value=TRUE; + + FUNC_ENTER_NOAPI(H5D_mpio_opt_possible, FAIL); + + /* Check args */ + assert(mem_space); + assert(file_space); + + /* Parallel I/O conversion flag must be set, if it is not collective IO, go to false. */ + if(!(flags&H5S_CONV_PAR_IO_POSSIBLE)) + HGOTO_DONE(FALSE); + + /* Check whether these are both simple or scalar dataspaces */ + if (!((H5S_SIMPLE==H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR==H5S_GET_EXTENT_TYPE(mem_space)) + && (H5S_SIMPLE==H5S_GET_EXTENT_TYPE(file_space) || H5S_SCALAR==H5S_GET_EXTENT_TYPE(file_space)))) + HGOTO_DONE(FALSE); + + /* Check whether both selections are "regular" */ + 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); + + /* 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); + + /* Dataset storage must be contiguous or chunked */ + if ((flags&H5S_CONV_STORAGE_MASK)!=H5S_CONV_STORAGE_CONTIGUOUS && + (flags&H5S_CONV_STORAGE_MASK)!=H5S_CONV_STORAGE_CHUNKED) + HGOTO_DONE(FALSE); + + 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 */ + 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 */ + tnum_chunkf, /* Number of chunks selection overlaps */ + max_chunkf, /* Maximum number of chunks selection overlaps */ + min_chunkf, /* Minimum number of chunks selection overlaps */ + num_chunks_same; /* Flag indicating whether all processes have the same # of chunks to operate on */ + unsigned dim_chunks; /* Temporary number of chunks in a dimension */ + MPI_Comm comm; /* MPI communicator for file */ + int mpi_rank; /* Rank in MPI communicator */ + int mpi_code; /* MPI return code */ + unsigned u; /* Local index variable */ + + /* Getting MPI communicator and rank */ + if((comm = H5F_mpi_get_comm(file))==MPI_COMM_NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator") + if((mpi_rank = H5F_mpi_get_rank(file))<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI rank") + + /* Currently collective chunking storage + inside HDF5 is supported for either one of the following two cases: + 1. All the hyperslabs for one process is inside one chunk. + 2. For single hyperslab selection, the number of chunks that covered + the single selection for all processes should be equal. + KY, 2004/7/14 + */ + + /* Quincey, please read. + This is maybe redundant, I think only when both memory and file space be SCALAR + space, the collective IO can work. Otherwise, SELECT_POINT will be reached,collective + IO shouldn't work. + Please clarify and correct the code on the following, + Quincey said that it was probably okay if only one data space is SCALAR, + Still keep the code here until we added more tests later. + Kent */ + if(H5S_SCALAR==H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR ==H5S_GET_EXTENT_TYPE(file_space)) { + if(!(H5S_SCALAR==H5S_GET_EXTENT_TYPE(mem_space) && H5S_SCALAR ==H5S_GET_EXTENT_TYPE(file_space))) + HGOTO_DONE(FALSE) + else + HGOTO_DONE(TRUE) + } /* end if */ + + dim_rankf = H5S_GET_EXTENT_NDIMS(file_space); + + if(H5S_SELECT_BOUNDS(file_space,startf,endf)==FAIL) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE,FAIL, "invalid check for single selection blocks"); + + for(u=0; u < layout->u.chunk.ndims; u++) + chunk_dim[u] = layout->u.chunk.dim[u]; + + /* Case 1: check whether all hyperslab in this process is inside one chunk. + Note: we don't handle when starting point is less than zero since that may cover + two chunks. */ + + /*for file space checking*/ + pcheck_hyper = 1; + for (u=0; u= H5_SIZEOF_OFF_T) -# define H5F_OVERFLOW_SIZET2OFFT(X) \ - ((size_t)(X)>=(size_t)((size_t)1<<(8*sizeof(off_t)-1))) -#else -# define H5F_OVERFLOW_SIZET2OFFT(X) 0 -#endif -#if (H5_SIZEOF_HSIZE_T >= H5_SIZEOF_OFF_T) -# define H5F_OVERFLOW_HSIZET2OFFT(X) \ - ((hsize_t)(X)>=(hsize_t)((hsize_t)1<<(8*sizeof(off_t)-1))) -#else -# define H5F_OVERFLOW_HSIZET2OFFT(X) 0 -#endif - -/* * Define the structure to store the file information for HDF5 files. One of * these structures is allocated per file, not per H5Fopen(). That is, set of * H5F_t structs can all point to the same H5F_file_t struct. The `nrefs' diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 3c64956..2401228 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -261,6 +261,23 @@ typedef struct H5F_t H5F_t; case 2: UINT16DECODE(p,l); break; \ } +/* + * Macros that check for overflows. These are somewhat dangerous to fiddle + * with. + */ +#if (H5_SIZEOF_SIZE_T >= H5_SIZEOF_OFF_T) +# define H5F_OVERFLOW_SIZET2OFFT(X) \ + ((size_t)(X)>=(size_t)((size_t)1<<(8*sizeof(off_t)-1))) +#else +# define H5F_OVERFLOW_SIZET2OFFT(X) 0 +#endif +#if (H5_SIZEOF_HSIZE_T >= H5_SIZEOF_OFF_T) +# define H5F_OVERFLOW_HSIZET2OFFT(X) \ + ((hsize_t)(X)>=(hsize_t)((hsize_t)1<<(8*sizeof(off_t)-1))) +#else +# define H5F_OVERFLOW_HSIZET2OFFT(X) 0 +#endif + /* ========= File Creation properties ============ */ /* Definitions for the size of the file user block in bytes */ #define H5F_CRT_USER_BLOCK_NAME "block_size" diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 0dada50..091dd42 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -17,7 +17,6 @@ * Tuesday, November 25, 1997 */ -#define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5O_PACKAGE /*suppress error about including H5Opkg */ /* Pablo information */ @@ -25,9 +24,8 @@ #define PABLO_MASK H5O_efl_mask #include "H5private.h" /* Generic Functions */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Fpkg.h" /* File access */ +#include "H5Fprivate.h" /* File access */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ @@ -40,10 +38,6 @@ static size_t H5O_efl_size(H5F_t *f, const void *_mesg); static herr_t H5O_efl_reset(void *_mesg); static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); -static herr_t H5O_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, - uint8_t *buf); -static herr_t H5O_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size, - const uint8_t *buf); /* This message derives from H5O */ const H5O_class_t H5O_EFL[1] = {{ @@ -428,341 +422,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_efl_read - * - * Purpose: Reads data from an external file list. It is an error to - * read past the logical end of file, but reading past the end - * of any particular member of the external file list results in - * zeros. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, March 4, 1998 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5O_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf) -{ - int fd=-1; - size_t to_read; -#ifndef NDEBUG - hsize_t tempto_read; -#endif /* NDEBUG */ - hsize_t skip=0; - haddr_t cur; - ssize_t n; - size_t u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5O_efl_read); - - /* Check args */ - assert (efl && efl->nused>0); - assert (H5F_addr_defined (addr)); - assert (size < SIZET_MAX); - assert (buf || 0==size); - - /* Find the first efl member from which to read */ - for (u=0, cur=0; unused; u++) { - if (H5O_EFL_UNLIMITED==efl->slot[u].size || addr < cur+efl->slot[u].size) { - skip = addr - cur; - break; - } - cur += efl->slot[u].size; - } - - /* Read the data */ - while (size) { - if (u>=efl->nused) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "read past logical end of file"); - if (H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset+skip)) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed"); - if ((fd=HDopen (efl->slot[u].name, O_RDONLY, 0))<0) - HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file"); - if (HDlseek (fd, (off_t)(efl->slot[u].offset+skip), SEEK_SET)<0) - HGOTO_ERROR (H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file"); -#ifndef NDEBUG - tempto_read = MIN(efl->slot[u].size-skip,(hsize_t)size); - H5_CHECK_OVERFLOW(tempto_read,hsize_t,size_t); - to_read = (size_t)tempto_read; -#else /* NDEBUG */ - to_read = MIN((size_t)(efl->slot[u].size-skip), size); -#endif /* NDEBUG */ - if ((n=HDread (fd, buf, to_read))<0) { - HGOTO_ERROR (H5E_EFL, H5E_READERROR, FAIL, "read error in external raw data file"); - } else if ((size_t)n=0) - HDclose (fd); - - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5O_efl_write - * - * Purpose: Writes data to an external file list. It is an error to - * write past the logical end of file, but writing past the end - * of any particular member of the external file list just - * extends that file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, March 4, 1998 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5O_efl_write (const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf) -{ - int fd=-1; - size_t to_write; -#ifndef NDEBUG - hsize_t tempto_write; -#endif /* NDEBUG */ - haddr_t cur; - hsize_t skip=0; - size_t u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5O_efl_write); - - /* Check args */ - assert (efl && efl->nused>0); - assert (H5F_addr_defined (addr)); - assert (size < SIZET_MAX); - assert (buf || 0==size); - - /* Find the first efl member in which to write */ - for (u=0, cur=0; unused; u++) { - if (H5O_EFL_UNLIMITED==efl->slot[u].size || addr < cur+efl->slot[u].size) { - skip = addr - cur; - break; - } - cur += efl->slot[u].size; - } - - /* Write the data */ - while (size) { - if (u>=efl->nused) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "write past logical end of file"); - if (H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset+skip)) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed"); - if ((fd=HDopen (efl->slot[u].name, O_CREAT|O_RDWR, 0666))<0) { - if (HDaccess (efl->slot[u].name, F_OK)<0) { - HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "external raw data file does not exist"); - } else { - HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file"); - } - } - if (HDlseek (fd, (off_t)(efl->slot[u].offset+skip), SEEK_SET)<0) - HGOTO_ERROR (H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file"); -#ifndef NDEBUG - tempto_write = MIN(efl->slot[u].size-skip,(hsize_t)size); - H5_CHECK_OVERFLOW(tempto_write,hsize_t,size_t); - to_write = (size_t)tempto_write; -#else /* NDEBUG */ - to_write = MIN((size_t)(efl->slot[u].size-skip), size); -#endif /* NDEBUG */ - if ((size_t)HDwrite (fd, buf, to_write)!=to_write) - HGOTO_ERROR (H5E_EFL, H5E_READERROR, FAIL, "write error in external raw data file"); - HDclose (fd); - fd = -1; - size -= to_write; - buf += to_write; - skip = 0; - u++; - } - -done: - if (fd>=0) - HDclose (fd); - - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5O_efl_readvv - * - * Purpose: Reads data from an external file list. It is an error to - * read past the logical end of file, but reading past the end - * of any particular member of the external file list results in - * zeros. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, May 7, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -ssize_t -H5O_efl_readvv(H5D_io_info_t *io_info, - size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], - size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[], - void *_buf) -{ - const H5O_efl_t *efl=&(io_info->store->efl); /* Pointer to efl info */ - unsigned char *buf; /* Pointer to buffer to write */ - haddr_t addr; /* Actual address to read */ - size_t size; /* Size of sequence in bytes */ - size_t u; /* Counting variable */ - size_t v; /* Counting variable */ - ssize_t ret_value=0; /* Return value */ - - FUNC_ENTER_NOAPI(H5O_efl_readvv, FAIL); - - /* Check args */ - assert (efl && efl->nused>0); - assert (_buf); - - /* Work through all the sequences */ - for(u=*dset_curr_seq, v=*mem_curr_seq; ustore->efl); /* Pointer to efl info */ - const unsigned char *buf; /* Pointer to buffer to write */ - haddr_t addr; /* Actual address to read */ - size_t size; /* Size of sequence in bytes */ - size_t u; /* Counting variable */ - size_t v; /* Counting variable */ - ssize_t ret_value=0; /* Return value */ - - FUNC_ENTER_NOAPI(H5O_efl_writevv, FAIL); - - /* Check args */ - assert (efl && efl->nused>0); - assert (_buf); - - /* Work through all the sequences */ - for(u=*dset_curr_seq, v=*mem_curr_seq; ustats[j].gath_ncalls && 0==path->stats[j].scat_ncalls && @@ -262,16 +255,18 @@ H5S_term_interface(void) } } } -#endif +#endif /* H5S_DEBUG */ /* Free data types */ H5I_destroy_group(H5I_DATASPACE); +#ifdef H5S_DEBUG /* Clear/free conversion table */ - for (i=0; iftype==H5S_GET_SELECT_TYPE(file_space) && - H5S_conv_g[i]->mtype==H5S_GET_SELECT_TYPE(mem_space)) { - -#ifdef H5_HAVE_PARALLEL - /* - * Check if we can set direct MPI-IO read/write functions - */ - opt=H5S_mpio_opt_possible(file,mem_space,file_space,flags,layout); - if(opt==FAIL) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, "invalid check for direct IO dataspace "); - - opt = H5S_get_collective_io_consensus(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 */ - H5S_conv_g[i]->read = H5D_mpio_spaces_read; - H5S_conv_g[i]->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 */ - H5S_conv_g[i]->read = H5S_select_read; - H5S_conv_g[i]->write = H5S_select_write; -#ifdef H5_HAVE_PARALLEL - } /* end else */ -#endif /* H5_HAVE_PARALLEL */ - - HGOTO_DONE(H5S_conv_g[i]); - } - } + for (u=0; uftype==H5S_GET_SELECT_TYPE(file_space) && + H5S_iostats_g[u]->mtype==H5S_GET_SELECT_TYPE(mem_space)) + HGOTO_DONE(H5S_iostats_g[u]); /* * The path wasn't found. Create a new path. @@ -1606,53 +1445,19 @@ const H5O_layout_t *layout path->ftype = H5S_GET_SELECT_TYPE(file_space); path->mtype = H5S_GET_SELECT_TYPE(mem_space); -#ifdef H5_HAVE_PARALLEL - /* - * Check if we can set direct MPI-IO read/write functions - */ - opt=H5S_mpio_opt_possible(file,mem_space,file_space,flags,layout); - if(opt==FAIL) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, "invalid check for direct IO dataspace "); - - opt = H5S_get_collective_io_consensus(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 */ - path->read = H5D_mpio_spaces_read; - path->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 */ - path->read = H5S_select_read; - path->write = H5S_select_write; -#ifdef H5_HAVE_PARALLEL - } /* end else */ -#endif /* H5_HAVE_PARALLEL */ - /* * Add the new path to the table. */ - if (H5S_nconv_g>=H5S_aconv_g) { - size_t n = MAX(10, 2*H5S_aconv_g); - H5S_conv_t **p = H5MM_realloc(H5S_conv_g, n*sizeof(H5S_conv_g[0])); + if (H5S_niostats_g>=H5S_aiostats_g) { + size_t n = MAX(10, 2*H5S_aiostats_g); + H5S_iostats_t **p = H5MM_realloc(H5S_iostats_g, n*sizeof(H5S_iostats_g[0])); if (NULL==p) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for data space conversion path table"); - H5S_aconv_g = n; - H5S_conv_g = p; + H5S_aiostats_g = n; + H5S_iostats_g = p; } /* end if */ - H5S_conv_g[H5S_nconv_g++] = path; + H5S_iostats_g[H5S_niostats_g++] = path; /* Set the return value */ ret_value=path; @@ -1664,7 +1469,8 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value); -} +} /* end H5S_find() */ +#endif /* H5S_DEBUG */ /*------------------------------------------------------------------------- diff --git a/src/H5Smpio.c b/src/H5Smpio.c index b8249e1..f1f171b 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -542,177 +542,4 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size, done: FUNC_LEAVE_NOAPI(ret_value); } - - -/*------------------------------------------------------------------------- - * Function: H5S_mpio_opt_possible - * - * Purpose: Checks if an direct I/O transfer is possible between memory and - * the file. - * - * Return: Success: Non-negative: TRUE or FALSE - * Failure: Negative - * - * Programmer: Quincey Koziol - * Wednesday, April 3, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5S_mpio_opt_possible( const H5F_t *file, const H5S_t *mem_space, const H5S_t *file_space, const unsigned flags,const H5O_layout_t *layout) -{ - htri_t c1,c2; /* Flags whether a selection is optimizable */ - htri_t ret_value=TRUE; - - FUNC_ENTER_NOAPI(H5S_mpio_opt_possible, FAIL); - - /* Check args */ - assert(mem_space); - assert(file_space); - - /* Parallel I/O conversion flag must be set, if it is not collective IO, go to false. */ - if(!(flags&H5S_CONV_PAR_IO_POSSIBLE)) - HGOTO_DONE(FALSE); - - /* Check whether these are both simple or scalar dataspaces */ - if (!((H5S_SIMPLE==H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR==H5S_GET_EXTENT_TYPE(mem_space)) - && (H5S_SIMPLE==H5S_GET_EXTENT_TYPE(file_space) || H5S_SCALAR==H5S_GET_EXTENT_TYPE(file_space)))) - HGOTO_DONE(FALSE); - - /* Check whether both selections are "regular" */ - 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); - - /* 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); - - /* Dataset storage must be contiguous or chunked */ - if ((flags&H5S_CONV_STORAGE_MASK)!=H5S_CONV_STORAGE_CONTIGUOUS && - (flags&H5S_CONV_STORAGE_MASK)!=H5S_CONV_STORAGE_CHUNKED) - HGOTO_DONE(FALSE); - - 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 */ - 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 */ - tnum_chunkf, /* Number of chunks selection overlaps */ - max_chunkf, /* Maximum number of chunks selection overlaps */ - min_chunkf, /* Minimum number of chunks selection overlaps */ - num_chunks_same; /* Flag indicating whether all processes have the same # of chunks to operate on */ - unsigned dim_chunks; /* Temporary number of chunks in a dimension */ - MPI_Comm comm; /* MPI communicator for file */ - int mpi_rank; /* Rank in MPI communicator */ - int mpi_code; /* MPI return code */ - unsigned u; /* Local index variable */ - - /* Getting MPI communicator and rank */ - if((comm = H5F_mpi_get_comm(file))==MPI_COMM_NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator") - if((mpi_rank = H5F_mpi_get_rank(file))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI rank") - - /* Currently collective chunking storage - inside HDF5 is supported for either one of the following two cases: - 1. All the hyperslabs for one process is inside one chunk. - 2. For single hyperslab selection, the number of chunks that covered - the single selection for all processes should be equal. - KY, 2004/7/14 - */ - - /* Quincey, please read. - This is maybe redundant, I think only when both memory and file space be SCALAR - space, the collective IO can work. Otherwise, SELECT_POINT will be reached,collective - IO shouldn't work. - Please clarify and correct the code on the following, - Quincey said that it was probably okay if only one data space is SCALAR, - Still keep the code here until we added more tests later. - Kent */ - if(H5S_SCALAR==mem_space->extent.type || H5S_SCALAR ==file_space->extent.type) { - if(!(H5S_SCALAR==mem_space->extent.type && H5S_SCALAR ==file_space->extent.type)) - HGOTO_DONE(FALSE) - else - HGOTO_DONE(TRUE) - } /* end if */ - - dim_rankf = file_space->extent.rank; - - if(H5S_SELECT_BOUNDS(file_space,startf,endf)==FAIL) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE,FAIL, "invalid check for single selection blocks"); - - for(u=0; u < layout->u.chunk.ndims; u++) - chunk_dim[u] = layout->u.chunk.dim[u]; - - /* Case 1: check whether all hyperslab in this process is inside one chunk. - Note: we don't handle when starting point is less than zero since that may cover - two chunks. */ - - /*for file space checking*/ - pcheck_hyper = 1; - for (u=0; u0); - assert (_buf); - assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER)); - - /* Allocate the vector I/O arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - } /* end if */ - else { - len=_len; - off=_off; - } /* end else */ - - /* Loop until all elements are written */ - while(nelmts>0) { - /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space,H5S_GET_SEQ_LIST_SORTED,iter,io_info->dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); - - /* Reset the current sequence information */ - mem_curr_seq=dset_curr_seq=0; - orig_mem_len=mem_len=nelem*iter->elmt_size; - mem_off=0; - - /* Write sequence list out */ - if ((*op)(io_info, nseq, &dset_curr_seq, len, off, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); - - /* Update buffer */ - buf += orig_mem_len; - - /* Decrement number of elements left to process */ - nelmts -= nelem; - } /* end while */ - -done: - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(len!=NULL) - H5FL_SEQ_FREE(size_t,len); - if(off!=NULL) - H5FL_SEQ_FREE(hsize_t,off); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_select_fscat() */ - - -/*------------------------------------------------------------------------- - * Function: H5S_select_fgath - * - * Purpose: Gathers data points from file F and accumulates them in the - * type conversion buffer BUF. The LAYOUT argument describes - * how the data is stored on disk and EFL describes how the data - * is organized in external files. ELMT_SIZE is the size in - * bytes of a datum which this function treats as opaque. - * FILE_SPACE describes the dataspace of the dataset on disk - * and the elements that have been selected for reading (via - * hyperslab, etc). This function will copy at most NELMTS - * elements. - * - * Return: Success: Number of elements copied. - * Failure: 0 - * - * Programmer: Quincey Koziol - * Monday, June 24, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5S_select_fgath (H5D_io_info_t *io_info, - H5O_layout_readvv_func_t op, - const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, - void *_buf/*out*/) -{ - uint8_t *buf=_buf; /* Alias for pointer arithmetic */ - hsize_t _off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets */ - hsize_t *off=NULL; /* Pointer to sequence offsets */ - hsize_t mem_off; /* Offset in memory */ - size_t mem_curr_seq; /* "Current sequence" in memory */ - size_t dset_curr_seq; /* "Current sequence" in dataset */ - size_t _len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths */ - size_t *len=NULL; /* Pointer to sequence lengths */ - size_t orig_mem_len, mem_len; /* Length of sequence in memory */ - size_t nseq; /* Number of sequences generated */ - size_t nelem; /* Number of elements used in sequences */ - size_t ret_value=nelmts; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_select_fgath, 0); - - /* Check args */ - assert (io_info); - assert (io_info->dset); - assert (io_info->store); - assert (space); - assert (iter); - assert (nelmts>0); - assert (_buf); - - /* Allocate the vector I/O arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O length vector array"); - if((off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O offset vector array"); - } /* end if */ - else { - len=_len; - off=_off; - } /* end else */ - - /* Loop until all elements are read */ - while(nelmts>0) { - /* Get list of sequences for selection to read */ - if(H5S_SELECT_GET_SEQ_LIST(space,H5S_GET_SEQ_LIST_SORTED,iter,io_info->dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed"); - - /* Reset the current sequence information */ - mem_curr_seq=dset_curr_seq=0; - orig_mem_len=mem_len=nelem*iter->elmt_size; - mem_off=0; - - /* Read sequence list in */ - if ((*op)(io_info, nseq, &dset_curr_seq, len, off, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); - - /* Update buffer */ - buf += orig_mem_len; - - /* Decrement number of elements left to process */ - nelmts -= nelem; - } /* end while */ - -done: - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(len!=NULL) - H5FL_SEQ_FREE(size_t,len); - if(off!=NULL) - H5FL_SEQ_FREE(hsize_t,off); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_select_fgath() */ - - -/*------------------------------------------------------------------------- - * Function: H5S_select_mscat - * - * Purpose: Scatters NELMTS data points from the scatter buffer - * TSCAT_BUF to the application buffer BUF. Each element is - * ELMT_SIZE bytes and they are organized in application memory - * according to SPACE. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, July 8, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5S_select_mscat (const void *_tscat_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, const H5D_dxpl_cache_t *dxpl_cache, - void *_buf/*out*/) -{ - uint8_t *buf=(uint8_t *)_buf; /* Get local copies for address arithmetic */ - const uint8_t *tscat_buf=(const uint8_t *)_tscat_buf; - hsize_t _off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets */ - hsize_t *off=NULL; /* Pointer to sequence offsets */ - size_t _len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths */ - size_t *len=NULL; /* Pointer to sequence lengths */ - size_t curr_len; /* Length of bytes left to process in sequence */ - size_t nseq; /* Number of sequences generated */ - size_t curr_seq; /* Current sequence being processed */ - size_t nelem; /* Number of elements used in sequences */ - herr_t ret_value=SUCCEED; /* Number of elements scattered */ - - FUNC_ENTER_NOAPI(H5S_select_mscat, FAIL); - - /* Check args */ - assert (tscat_buf); - assert (space); - assert (iter); - assert (nelmts>0); - assert (buf); - - /* Allocate the vector I/O arrays */ - if(dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((len = H5FL_SEQ_MALLOC(size_t,dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((off = H5FL_SEQ_MALLOC(hsize_t,dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - } /* end if */ - else { - len=_len; - off=_off; - } /* end else */ - - /* Loop until all elements are written */ - while(nelmts>0) { - /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space,0,iter,dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed"); - - /* Loop, while sequences left to process */ - for(curr_seq=0; curr_seqvec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(len!=NULL) - H5FL_SEQ_FREE(size_t,len); - if(off!=NULL) - H5FL_SEQ_FREE(hsize_t,off); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_select_mscat() */ - - -/*------------------------------------------------------------------------- - * Function: H5S_select_mgath - * - * Purpose: Gathers dataset elements from application memory BUF and - * copies them into the gather buffer TGATH_BUF. - * Each element is ELMT_SIZE bytes and arranged in application - * memory according to SPACE. - * The caller is requesting that at most NELMTS be gathered. - * - * Return: Success: Number of elements copied. - * Failure: 0 - * - * Programmer: Quincey Koziol - * Monday, June 24, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5S_select_mgath (const void *_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, const H5D_dxpl_cache_t *dxpl_cache, - void *_tgath_buf/*out*/) -{ - const uint8_t *buf=(const uint8_t *)_buf; /* Get local copies for address arithmetic */ - uint8_t *tgath_buf=(uint8_t *)_tgath_buf; - hsize_t _off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets */ - hsize_t *off=NULL; /* Pointer to sequence offsets */ - size_t _len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths */ - size_t *len=NULL; /* Pointer to sequence lengths */ - size_t curr_len; /* Length of bytes left to process in sequence */ - size_t nseq; /* Number of sequences generated */ - size_t curr_seq; /* Current sequence being processed */ - size_t nelem; /* Number of elements used in sequences */ - size_t ret_value=nelmts; /* Number of elements gathered */ - - FUNC_ENTER_NOAPI(H5S_select_mgath, 0); - - /* Check args */ - assert (buf); - assert (space); - assert (iter); - assert (nelmts>0); - assert (tgath_buf); - - /* Allocate the vector I/O arrays */ - if(dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((len = H5FL_SEQ_MALLOC(size_t,dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O length vector array"); - if((off = H5FL_SEQ_MALLOC(hsize_t,dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O offset vector array"); - } /* end if */ - else { - len=_len; - off=_off; - } /* end else */ - - /* Loop until all elements are written */ - while(nelmts>0) { - /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space,0,iter,dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed"); - - /* Loop, while sequences left to process */ - for(curr_seq=0; curr_seqvec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(len!=NULL) - H5FL_SEQ_FREE(size_t,len); - if(off!=NULL) - H5FL_SEQ_FREE(hsize_t,off); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_select_mgath() */ - - -/*------------------------------------------------------------------------- - * Function: H5S_select_read - * - * Purpose: Reads directly from file into application memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 23, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5S_select_read(H5D_io_info_t *io_info, - H5O_layout_readvv_func_t op, - size_t nelmts, size_t elmt_size, - const H5S_t *file_space, const H5S_t *mem_space, - void *buf/*out*/) -{ - H5S_sel_iter_t mem_iter; /* Memory selection iteration info */ - hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */ - H5S_sel_iter_t file_iter; /* File selection iteration info */ - hbool_t file_iter_init=0; /* File selection iteration info has been initialized */ - hsize_t _mem_off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets in memory */ - hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */ - hsize_t _file_off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets in the file */ - hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */ - size_t _mem_len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths in memory */ - size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */ - size_t _file_len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths in the file */ - size_t *file_len=NULL; /* Pointer to sequence lengths in the file */ - size_t mem_nseq; /* Number of sequences generated in the file */ - size_t file_nseq; /* Number of sequences generated in memory */ - size_t mem_nelem; /* Number of elements used in memory sequences */ - size_t file_nelem; /* Number of elements used in file sequences */ - size_t curr_mem_seq; /* Current memory sequence to operate on */ - size_t curr_file_seq; /* Current file sequence to operate on */ - ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_select_read, FAIL); - - /* Check args */ - assert(io_info); - assert(io_info->dset); - assert(io_info->dxpl_cache); - assert(io_info->store); - assert(buf); - assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER)); - - /* Initialize file iterator */ - if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); - file_iter_init=1; /* File selection iteration info has been initialized */ - - /* Initialize memory iterator */ - if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); - mem_iter_init=1; /* Memory selection iteration info has been initialized */ - - /* Allocate the vector I/O arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - } /* end if */ - else { - mem_len=_mem_len; - mem_off=_mem_off; - file_len=_file_len; - file_off=_file_off; - } /* end else */ - - /* Initialize sequence counts */ - curr_mem_seq=curr_file_seq=0; - mem_nseq=file_nseq=0; - - /* Loop, until all bytes are processed */ - while(nelmts>0) { - /* Check if more file sequences are needed */ - if(curr_file_seq>=file_nseq) { - /* Get sequences for file selection */ - if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); - - /* Start at the beginning of the sequences again */ - curr_file_seq=0; - } /* end if */ - - /* Check if more memory sequences are needed */ - if(curr_mem_seq>=mem_nseq) { - /* Get sequences for memory selection */ - if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); - - /* Start at the beginning of the sequences again */ - curr_mem_seq=0; - } /* end if */ - - /* Read file sequences into current memory sequence */ - if ((tmp_file_len=(*op)(io_info, - file_nseq, &curr_file_seq, file_len, file_off, - mem_nseq, &curr_mem_seq, mem_len, mem_off, - buf))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); - - /* Decrement number of elements left to process */ - assert((tmp_file_len%elmt_size)==0); - nelmts-=(tmp_file_len/elmt_size); - } /* end while */ - -done: - /* Release file selection iterator */ - if(file_iter_init) { - if (H5S_SELECT_ITER_RELEASE(&file_iter)<0) - HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); - } /* end if */ - - /* Release memory selection iterator */ - if(mem_iter_init) { - if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0) - HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); - } /* end if */ - - /* Free vector arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(file_len!=NULL) - H5FL_SEQ_FREE(size_t,file_len); - if(file_off!=NULL) - H5FL_SEQ_FREE(hsize_t,file_off); - if(mem_len!=NULL) - H5FL_SEQ_FREE(size_t,mem_len); - if(mem_off!=NULL) - H5FL_SEQ_FREE(hsize_t,mem_off); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5S_select_read() */ - - -/*------------------------------------------------------------------------- - * Function: H5S_select_write - * - * Purpose: Writes directly from application memory into a file - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 23, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5S_select_write(H5D_io_info_t *io_info, - H5O_layout_writevv_func_t op, - size_t nelmts, size_t elmt_size, - const H5S_t *file_space, const H5S_t *mem_space, - const void *buf/*out*/) -{ - H5S_sel_iter_t mem_iter; /* Memory selection iteration info */ - hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */ - H5S_sel_iter_t file_iter; /* File selection iteration info */ - hbool_t file_iter_init=0; /* File selection iteration info has been initialized */ - hsize_t _mem_off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets in memory */ - hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */ - hsize_t _file_off[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence offsets in the file */ - hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */ - size_t _mem_len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths in memory */ - size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */ - size_t _file_len[H5D_XFER_HYPER_VECTOR_SIZE_DEF]; /* Array to store sequence lengths in the file */ - size_t *file_len=NULL; /* Pointer to sequence lengths in the file */ - size_t mem_nseq; /* Number of sequences generated in the file */ - size_t file_nseq; /* Number of sequences generated in memory */ - size_t mem_nelem; /* Number of elements used in memory sequences */ - size_t file_nelem; /* Number of elements used in file sequences */ - size_t curr_mem_seq; /* Current memory sequence to operate on */ - size_t curr_file_seq; /* Current file sequence to operate on */ - ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_select_write, FAIL); - - /* Check args */ - assert(io_info); - assert(io_info->dset); - assert(io_info->store); - assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER)); - assert(buf); - - /* Allocate the vector I/O arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); - if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); - } /* end if */ - else { - mem_len=_mem_len; - mem_off=_mem_off; - file_len=_file_len; - file_off=_file_off; - } /* end else */ - - /* Initialize file iterator */ - if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); - file_iter_init=1; /* File selection iteration info has been initialized */ - - /* Initialize memory iterator */ - if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); - mem_iter_init=1; /* Memory selection iteration info has been initialized */ - - /* Initialize sequence counts */ - curr_mem_seq=curr_file_seq=0; - mem_nseq=file_nseq=0; - - /* Loop, until all bytes are processed */ - while(nelmts>0) { - /* Check if more file sequences are needed */ - if(curr_file_seq>=file_nseq) { - /* Get sequences for file selection */ - if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); - - /* Start at the beginning of the sequences again */ - curr_file_seq=0; - } /* end if */ - - /* Check if more memory sequences are needed */ - if(curr_mem_seq>=mem_nseq) { - /* Get sequences for memory selection */ - if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); - - /* Start at the beginning of the sequences again */ - curr_mem_seq=0; - } /* end if */ - - /* Write memory sequences into file sequences */ - if ((tmp_file_len=(*op)(io_info, - file_nseq, &curr_file_seq, file_len, file_off, - mem_nseq, &curr_mem_seq, mem_len, mem_off, - buf))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); - - /* Decrement number of elements left to process */ - assert((tmp_file_len%elmt_size)==0); - nelmts-=(tmp_file_len/elmt_size); - } /* end while */ - -done: - /* Release file selection iterator */ - if(file_iter_init) { - if (H5S_SELECT_ITER_RELEASE(&file_iter)<0) - HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); - } /* end if */ - - /* Release memory selection iterator */ - if(mem_iter_init) { - if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0) - HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); - } /* end if */ - - /* Free vector arrays */ - if(io_info->dxpl_cache->vec_size!=H5D_XFER_HYPER_VECTOR_SIZE_DEF) { - if(file_len!=NULL) - H5FL_SEQ_FREE(size_t,file_len); - if(file_off!=NULL) - H5FL_SEQ_FREE(hsize_t,file_off); - if(mem_len!=NULL) - H5FL_SEQ_FREE(size_t,mem_len); - if(mem_off!=NULL) - H5FL_SEQ_FREE(hsize_t,mem_off); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5S_select_write() */ - diff --git a/src/H5T.c b/src/H5T.c index f6462db..033feed 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -1418,13 +1418,13 @@ H5Topen(hid_t loc_id, const char *name) if ((type=H5T_open (&ent, dxpl_id)) ==NULL) HGOTO_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named data type"); - /* Register an atom for the datatype */ - if ((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register type"); + /* Register the type and return the ID */ + if ((ret_value=H5I_register (H5I_DATATYPE, type))<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named data type"); done: - if(ret_value <0) - if(type !=NULL) + if(ret_value<0) + if(type!=NULL) H5T_close(type); FUNC_LEAVE_API(ret_value); @@ -2363,7 +2363,7 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5FL_FREE(H5T_path_t,path); H5E_clear(); /*ignore all shutdown errors*/ } /* end else */ - } + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value); @@ -2686,7 +2686,7 @@ H5T_create(H5T_class_t type, size_t size) } dt->ent.header = HADDR_UNDEF; - dt->shared->fo_count =1; + dt->shared->fo_count = 1; dt->shared->size = size; /* Set return value */ @@ -2846,16 +2846,18 @@ H5T_open_oid (H5G_entry_t *ent, hid_t dxpl_id) if(NULL==(dt=H5FL_CALLOC(H5T_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - if(NULL==(dt->shared=H5FL_MALLOC(H5T_t))) + if(NULL==(dt->shared=H5FL_MALLOC(H5T_shared_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if (H5O_open (ent)<0) HGOTO_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named data type"); + /* The fourth argument to H5O_read is dt because we've already CALLOC'ed memory for it */ if (NULL==(dt=H5O_read (ent, H5O_DTYPE_ID, 0, dt, dxpl_id))) HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to load type message from object header"); /* Mark the type as named and open */ dt->shared->state = H5T_STATE_OPEN; + /* Shallow copy (take ownership) of the group entry object */ H5G_ent_copy(&(dt->ent),ent,H5G_COPY_SHALLOW); @@ -2923,7 +2925,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) assert(old_dt); /* Allocate space */ - if (NULL==(new_dt = H5FL_CALLOC(H5T_t))) + if (NULL==(new_dt = H5FL_MALLOC(H5T_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); if (NULL==(new_dt->shared = H5FL_MALLOC(H5T_shared_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); @@ -2934,7 +2936,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) new_dt->shared->fo_count = 1; /* Copy parent information */ - if (new_dt->shared && new_dt->shared->parent) + if (new_dt->shared->parent) new_dt->shared->parent = H5T_copy(new_dt->shared->parent, method); /* Check what sort of copy we are making */ @@ -2966,6 +2968,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) * type. Immutable transient types are degraded to read-only. */ if (H5F_addr_defined(new_dt->ent.header)) { + /* Check if the object is already open */ if((reopened_fo=H5FO_opened(new_dt->ent.file,new_dt->ent.header))==NULL) { /* Clear any errors from H5FO_opened() */ H5E_clear(); @@ -3038,8 +3041,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) /* If the field changed size, add that change to the accumulated size change */ if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) { /* Adjust the size of the member */ - new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/ - old_dt->shared->u.compnd.memb[old_match].type->shared->size; + new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size; accum_change += (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size); } /* end if */ @@ -3187,11 +3189,12 @@ H5T_free(H5T_t *dt) assert(dt && dt->shared); /* - * If a named type is being closed then close the object header also. + * If a named type is being closed then close the object header and + * remove from the list of open objects in the file. */ if (H5T_STATE_OPEN==dt->shared->state) { assert (H5F_addr_defined(dt->ent.header)); - /* Remove the dataset from the list of opened objects in the file */ + /* Remove the datatype from the list of opened objects in the file */ if(H5FO_delete(dt->ent.file, H5AC_dxpl_id, dt->ent.header)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't remove datatype from list of open objects") if (H5O_close(&(dt->ent))<0) @@ -4604,8 +4607,15 @@ H5T_print_stats(H5T_path_t UNUSED * path, int UNUSED * nprint/*in,out*/) "----------", "-----", "-----", "----", "------", "-------", "---------"); } - nbytes = MAX (H5T_get_size (path->src), - H5T_get_size (path->dst)); + if(path->src && path->dst) + nbytes = MAX (H5T_get_size (path->src), + H5T_get_size (path->dst)); + else if(path->src) + nbytes = H5T_get_size (path->src); + else if(path->dst) + nbytes = H5T_get_size (path->dst); + else + nbytes = 0; nbytes *= path->stats.nelmts; H5_bandwidth(bandwidth, (double)nbytes, path->stats.timer.etime); diff --git a/src/Makefile.in b/src/Makefile.in index 21ccab1..ffd8cef 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -30,8 +30,9 @@ LIB=libhdf5.la DISTCLEAN=libhdf5.settings ## Source and object files for the library (lexicographically)... -LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5Dcontig.c H5Dcompact.c H5Dio.c \ - H5Distore.c H5Dmpio.c H5Dtest.c H5E.c H5F.c H5FD.c \ +LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5Dcontig.c H5Dcompact.c H5Defl.c \ + H5Dio.c H5Distore.c H5Dmpio.c H5Dselect.c H5Dtest.c H5E.c H5F.c \ + H5FD.c \ H5FDcore.c H5FDfamily.c H5FDgass.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDsrb.c H5FDstdio.c \ H5FDstream.c H5FL.c H5FO.c H5FS.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c \ -- cgit v0.12