summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Dio.c650
-rw-r--r--src/H5Distore.c24
-rw-r--r--src/H5Fistore.c24
-rw-r--r--src/H5S.c69
-rw-r--r--src/H5Shyper.c452
-rw-r--r--src/H5Sprivate.h13
-rw-r--r--src/H5Sselect.c176
7 files changed, 1234 insertions, 174 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c
index c1f6d4b..731b4c7 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -65,9 +65,10 @@ typedef struct fm_map {
H5TB_TREE *fsel; /* TBBT containing file dataspaces for all chunks */
H5TB_TREE *msel; /* TBBT containing memory dataspaces for all chunks */
hsize_t last_index; /* Index of last chunk operated on */
- H5S_t *last_fchunk; /* Pointer to last file chunk's dataspace */
+ H5S_t *file_space; /* Pointer to the file dataspace */
+ H5S_t *mem_space; /* Pointer to the memory dataspace */
+ hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */
H5S_t *last_mchunk; /* Pointer to last memory chunk's dataspace */
- H5S_t *fchunk_tmpl; /* Dataspace template for new file chunks */
H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */
unsigned f_ndims; /* Number of dimensions for file dataspace */
H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
@@ -120,7 +121,9 @@ static void H5D_free_fchunk_info(void *fchunk_info);
static void H5D_free_mchunk_info(void *mchunk_info);
static herr_t H5D_chunk_coords_assist(hssize_t *coords, size_t ndims,
hsize_t chunks[], hsize_t chunk_idx);
-static herr_t H5D_chunk_cb(void *elem, hid_t type_id, hsize_t ndims,
+static herr_t H5D_create_chunk_file_map(fm_map *fm);
+static herr_t H5D_create_chunk_mem_map(fm_map *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);
@@ -1837,9 +1840,27 @@ nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
FUNC_ENTER_NOINIT(H5D_chunk_write);
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Entering, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
/* Map elements between file and memory for each chunk*/
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");
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - After creating chunk map, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
/*
* If there is no type conversion then write directly from the
@@ -1849,6 +1870,15 @@ nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#ifdef H5S_DEBUG
H5_timer_begin(&timer);
#endif
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Performing optimized I/O, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
/* Get first node in chunk trees */
fchunk_node=H5TB_first(fm.fsel->root);
mchunk_node=H5TB_first(fm.msel->root);
@@ -1896,6 +1926,15 @@ nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
*/
assert((fchunk_node && mchunk_node) || (!fchunk_node && !mchunk_node));
} /* end while */
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Done performing optimized I/O, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].write_timer), &timer);
@@ -1906,6 +1945,13 @@ nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* direct xfer accomplished successfully */
HGOTO_DONE(SUCCEED);
} /* end if */
+#ifdef QAK
+{
+ int mpi_rank;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ HDfprintf(stderr,"%s: rank=%d - Performing NON-optimized I/O\n",FUNC,mpi_rank);
+}
+#endif /* QAK */
/*
* This is the general case(type conversion).
@@ -2242,14 +2288,13 @@ 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)
{
- H5S_t *tmp_fspace=NULL, /* Temporary file dataspace */
- *tmp_mspace=NULL; /* Temporary memory dataspace */
+ H5S_t *tmp_mspace=NULL; /* Temporary memory dataspace */
hid_t f_tid=(-1); /* Temporary copy of file datatype for iteration */
size_t elmt_size; /* Memory datatype size */
hbool_t iter_init=0; /* Selection iteration info has been initialized */
unsigned f_ndims; /* The number of dimensions of the file's dataspace */
int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
- hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* Dimensionality of file dataspace */
+ hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of selection for chunk */
hsize_t nchunks, last_nchunks; /* Number of chunks in dataset */
H5TB_NODE *curr_node; /* Current node in TBBT */
char bogus; /* "bogus" buffer to pass to selection iterator */
@@ -2257,6 +2302,15 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOINIT(H5D_create_chunk_map);
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Entering, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
/* Initialize fm_map structure */
HDmemset(fm, 0, sizeof(fm_map));
@@ -2264,34 +2318,29 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp
/* Get layout for dataset */
fm->layout = &(dataset->layout);
- /* Create a file space of a chunk's size, instead of whole file space*/
- if(NULL==(tmp_fspace=H5S_create_simple((dataset->layout.ndims-1),dataset->layout.dim,NULL)))
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
-
/*make a copy of mem_space*/
if((tmp_mspace = H5S_copy(mem_space))==NULL)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
- /*de-select the file space and mem space copies*/
- if(H5S_select_none(tmp_fspace)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select file space");
- if(H5S_select_none(tmp_mspace)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space");
-
/* Get dim number and dimensionality for each dataspace */
fm->f_ndims=f_ndims=dataset->layout.ndims-1;
if((sm_ndims = H5S_get_simple_extent_ndims(tmp_mspace))<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number");
fm->m_ndims=sm_ndims;
- if(H5S_get_simple_extent_dims(file_space, f_dims, NULL)<0)
+ /* De-select the mem space copy */
+ if(H5S_select_none(tmp_mspace)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space");
+
+ if(H5S_get_simple_extent_dims(file_space, fm->f_dims, NULL)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
/* Decide the number of chunks in each dimension*/
last_nchunks=0;
nchunks=1;
for(u=0; u<f_ndims; u++) {
- fm->chunks[u] = ((f_dims[u]+dataset->layout.dim[u])-1) / dataset->layout.dim[u];
+ /* Round up to the next integer # of chunks, to accomodate partial chunks */
+ fm->chunks[u] = ((fm->f_dims[u]+dataset->layout.dim[u])-1) / dataset->layout.dim[u];
/* Track total number of chunks in dataset */
nchunks *= fm->chunks[u];
@@ -2312,28 +2361,47 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp
if((fm->msel=H5TB_fast_dmake(H5TB_FAST_HSIZE_COMPARE))==NULL)
HGOTO_ERROR(H5E_DATASET,H5E_CANTMAKETREE,FAIL,"can't create TBBT for memory chunk selections");
- /* Save chunk template information */
- fm->fchunk_tmpl=tmp_fspace;
- fm->mchunk_tmpl=tmp_mspace;
+ /* Save chunk template information */
+ fm->mchunk_tmpl=tmp_mspace;
- /* Initialize "last chunk" information */
- fm->last_index=(hsize_t)-1;
- fm->last_fchunk=fm->last_mchunk=NULL;
-
- /* Create temporary datatypes for selection iteration */
- if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype");
-
- /* Create selection iterator for memory selection */
- if((elmt_size=H5T_get_size(mem_type))==0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
- if (H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- iter_init=1; /* Selection iteration info has been initialized */
+ /* Initialize "last chunk" information */
+ fm->last_index=(hsize_t)-1;
+ fm->last_mchunk=NULL;
+
+ /* Copy the file dataspace */
+ if((fm->file_space = H5S_copy(file_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file dataspace");
+ if(H5S_hyper_convert(fm->file_space)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees");
- /* Build the file & memory selection for each chunk */
- if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_cb, fm)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to iterate file space");
+ /* Copy the memory dataspace */
+ if((fm->mem_space = H5S_copy(mem_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory dataspace");
+ if(H5S_hyper_convert(fm->mem_space)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees");
+
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Before creating chunk selections, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
+ /* Build the file selection for each chunk */
+ if(H5D_create_chunk_file_map(fm)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections");
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - After creating file chunk selections, time=%f\n",FUNC,mpi_rank,time);
+ HDfprintf(stderr,"%s: rank=%d - H5S_select_shape_same=%d\n",FUNC,mpi_rank,H5S_select_shape_same(file_space,mem_space));
+}
+#endif /* QAK */
/* Clean file chunks' hyperslab span "scratch" information */
curr_node=H5TB_first(fm->fsel->root);
@@ -2352,34 +2420,64 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp
curr_node=H5TB_next(curr_node);
} /* end while */
- /* Clean memory chunks' hyperslab span "scratch" information */
- curr_node=H5TB_first(fm->msel->root);
- while(curr_node) {
- H5D_mchunk_info_t *chunk_info; /* Pointer chunk information */
-
- /* Get pointer to chunk's information */
- chunk_info=curr_node->data;
- assert(chunk_info);
-
- /* Clean hyperslab span's "scratch" information */
- if(H5S_hyper_reset_scratch(chunk_info->space)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info");
+ /* Build the memory selection for each chunk */
+ if(H5S_select_shape_same(file_space,mem_space)==TRUE) {
+ /* If the selections are the same shape, use the file chunk information
+ * to generate the memory chunk information quickly.
+ */
+ if(H5D_create_chunk_mem_map(fm)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections");
+ } /* end if */
+ else {
+ /* Create temporary datatypes for selection iteration */
+ if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype");
+
+ /* Create selection iterator for memory selection */
+ if((elmt_size=H5T_get_size(mem_type))==0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
+ if (H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ iter_init=1; /* Selection iteration info has been initialized */
+
+ /* Spaces aren't the same shape, iterate over the memory selection directly */
+ if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_mem_cb, fm)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections");
+
+ /* Clean memory chunks' hyperslab span "scratch" information */
+ curr_node=H5TB_first(fm->msel->root);
+ while(curr_node) {
+ H5D_mchunk_info_t *chunk_info; /* Pointer chunk information */
+
+ /* Get pointer to chunk's information */
+ chunk_info=curr_node->data;
+ assert(chunk_info);
+
+ /* Clean hyperslab span's "scratch" information */
+ if(H5S_hyper_reset_scratch(chunk_info->space)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info");
+
+ /* Get the next chunk node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end else */
- /* Get the next chunk node in the TBBT */
- curr_node=H5TB_next(curr_node);
- } /* end while */
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - After creating chunk selections, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
done:
/* Release the [potentially partially built] chunk mapping information if an error occurs */
if(ret_value<0) {
- if(tmp_fspace && !fm->fchunk_tmpl) {
- if(H5S_close(tmp_fspace)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file chunk dataspace template");
- } /* end if */
-
if(tmp_mspace && !fm->mchunk_tmpl) {
if(H5S_close(tmp_mspace)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template");
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template");
} /* end if */
if (H5D_destroy_chunk_map(fm)<0)
@@ -2393,6 +2491,15 @@ done:
if(f_tid!=(-1))
H5Tclose(f_tid);
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Leaving, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_create_chunk_map() */
@@ -2500,10 +2607,15 @@ H5D_destroy_chunk_map(fm_map *fm)
if(fm->msel)
H5TB_dfree(fm->msel,H5D_free_mchunk_info,NULL);
- /* Free the file chunk dataspace template */
- if(fm->fchunk_tmpl)
- if(H5S_close(fm->fchunk_tmpl)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file chunk dataspace template");
+ /* Free the file dataspace */
+ if(fm->file_space)
+ if(H5S_close(fm->file_space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file dataspace");
+
+ /* Free the memory dataspace */
+ if(fm->mem_space)
+ if(H5S_close(fm->mem_space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory dataspace");
/* Free the memory chunk dataspace template */
if(fm->mchunk_tmpl)
@@ -2516,10 +2628,338 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_cb
+ * Function: H5D_create_chunk_file_map
+ *
+ * Purpose: Create all chunk selections in file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, May 29, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_create_chunk_file_map(fm_map *fm)
+{
+ H5S_t *tmp_fspace=NULL; /* Temporary file dataspace */
+ hssize_t sel_points; /* Number of elements in file selection */
+ hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
+ hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
+ hssize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
+ hssize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
+ hsize_t count[H5O_LAYOUT_NDIMS]; /* Hyperslab count information */
+ hsize_t chunk_index; /* Index of chunk */
+ int curr_dim; /* Current dimension to increment */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_create_chunk_file_map);
+
+ /* Make a copy of file dataspace */
+ if((tmp_fspace = H5S_copy(fm->file_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
+
+ /* Get number of elements selected in file */
+ if((sel_points=H5S_get_select_npoints(tmp_fspace))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements");
+
+ /* Get offset of first block in file selection */
+ if(H5S_get_select_bounds(tmp_fspace, sel_start, sel_end)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info");
+
+ /* Set initial chunk location & hyperslab size */
+ for(u=0; u<fm->f_ndims; u++) {
+ start_coords[u]=(sel_start[u]/fm->layout->dim[u])*fm->layout->dim[u];
+ coords[u]=start_coords[u];
+ count[u]=fm->layout->dim[u];
+ } /* end for */
+
+ /* Select initial chunk as hyperslab */
+ if(H5S_select_hyperslab(tmp_fspace,H5S_SELECT_SET,coords,NULL,count,NULL)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create hyperslab selection");
+
+ /* Calculate the index of this chunk */
+ if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index");
+
+ /* Iterate through each chunk in the dataset */
+ while(1) {
+ /* Check for intersection of temporary chunk and file selection */
+ if(H5S_hyper_intersect(tmp_fspace,fm->file_space)==TRUE) {
+ H5S_t *tmp_fchunk; /* Temporary file dataspace */
+ H5D_fchunk_info_t *new_fchunk_info; /* File chunk information to insert into tree */
+ hssize_t chunk_points; /* Number of elements in chunk selection */
+
+ /* Create "temporary" chunk for selection operations (copy file space) */
+ if((tmp_fchunk = H5S_copy(fm->file_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
+
+ /* "AND" temporary chunk and current chunk */
+ if(H5S_select_hyperslab(tmp_fchunk,H5S_SELECT_AND,coords,NULL,count,NULL)<0) {
+ H5S_close(tmp_fchunk);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create chunk selection");
+ } /* end if */
+
+ /* Resize chunk's dataspace dimensions to size of chunk */
+ if(H5S_set_extent_real(tmp_fchunk,count)<0) {
+ H5S_close(tmp_fchunk);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions");
+ } /* end if */
+
+ /* Move selection back to have correct offset in chunk */
+ if(H5S_hyper_adjust(tmp_fchunk,coords)<0) {
+ H5S_close(tmp_fchunk);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection");
+ } /* end if */
+
+ /* Add temporary chunk to the list of file chunks */
+
+ /* Allocate the file & memory chunk information */
+ if (NULL==(new_fchunk_info = H5FL_MALLOC (H5D_fchunk_info_t))) {
+ H5S_close(tmp_fchunk);
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate file chunk info");
+ } /* end if */
+
+ /* Initialize the file chunk information */
+
+ /* Set the chunk index */
+ new_fchunk_info->index=chunk_index;
+
+ /* Set the file chunk dataspace */
+ new_fchunk_info->space=tmp_fchunk;
+
+ /* Compute the chunk's coordinates */
+ H5D_chunk_coords_assist(new_fchunk_info->coords, fm->f_ndims, fm->chunks, chunk_index);
+
+ /* Insert the new file chunk into the TBBT tree */
+ if(H5TB_dins(fm->fsel,new_fchunk_info,new_fchunk_info)==NULL) {
+ H5D_free_fchunk_info(new_fchunk_info);
+ HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert file chunk into TBBT");
+ } /* end if */
+
+ /* Get number of elements selected in chunk */
+ if((chunk_points=H5S_get_select_npoints(tmp_fchunk))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements");
+
+ /* Decrement # of points left in file selection */
+ sel_points-=chunk_points;
+
+ /* Leave if we are done */
+ if(sel_points==0)
+ HGOTO_DONE(SUCCEED);
+ assert(sel_points>0);
+ } /* end if */
+
+ /* Increment chunk index */
+ chunk_index++;
+
+ /* Set current increment dimension */
+ curr_dim=fm->f_ndims-1;
+
+ /* Increment chunk location in fastest changing dimension */
+ coords[curr_dim]+=count[curr_dim];
+
+ /* Bring chunk location back into bounds, if necessary */
+ if(coords[curr_dim]>sel_end[curr_dim]) {
+ do {
+ /* Reset current dimension's location to 0 */
+ coords[curr_dim]=start_coords[curr_dim];
+
+ /* Decrement current dimension */
+ curr_dim--;
+
+ /* Increment chunk location in current dimension */
+ coords[curr_dim]+=count[curr_dim];
+ } while(coords[curr_dim]>sel_end[curr_dim]);
+
+ /* Re-Calculate the index of this chunk */
+ if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index");
+ } /* end if */
+
+ /* Move template chunk's offset to current location of chunk */
+ if(H5S_hyper_move(tmp_fspace,coords)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't move chunk selection");
+ } /* end while */
+
+done:
+ if(tmp_fspace)
+ if(H5S_close(tmp_fspace)<0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file dataspace copy");
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_create_chunk_file_map() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_create_chunk_mem_map
+ *
+ * Purpose: Create all chunk selections in memory by copying the file
+ * chunk selections and adjusting their offsets to be correct
+ * for the memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, May 29, 2003
+ *
+ * Assumptions: That the file and memory selections are the same shape.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_create_chunk_mem_map(fm_map *fm)
+{
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ hsize_t file_off[H5O_LAYOUT_NDIMS*2]; /* Offset of first block in file selection */
+ hsize_t mem_off[H5O_LAYOUT_NDIMS*2]; /* Offset of first block in memory selection */
+ hssize_t adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to all file chunks */
+ hssize_t chunk_adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to a particular chunk */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_create_chunk_mem_map);
+#ifdef QAK
+{
+ hsize_t mem_dims[H5O_LAYOUT_NDIMS]; /* Dimensions of memory space */
+
+ if(H5S_get_simple_extent_dims(fm->mem_space, mem_dims, NULL)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
+
+ HDfprintf(stderr,"%s: mem_dims={",FUNC);
+ for(u=0; u<fm->m_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",mem_dims[u],(u<(fm->m_ndims-1) ? ", " : "}\n"));
+}
+#endif /* QAK */
+
+ /* Get offset of first block in file selection */
+ if(H5S_get_select_hyper_blocklist(fm->file_space, 0, 1, file_off)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection block info");
+
+ /* Get offset of first block in memory selection */
+ if(H5S_get_select_hyper_blocklist(fm->mem_space, 0, 1, mem_off)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection block info");
+
+ /* Calculate the adjustment for memory selection from file selection */
+ assert(fm->m_ndims==fm->f_ndims);
+ for(u=0; u<fm->f_ndims; u++)
+ adjust[u]=file_off[u]-mem_off[u];
+#ifdef QAK
+{
+ int mpi_rank;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ if(mpi_rank==1) {
+ HDfprintf(stderr,"%s: rank=%d - adjust={",FUNC,mpi_rank);
+ for(u=0; u<fm->f_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",adjust[u],(u<(fm->f_ndims-1) ? ", " : "}\n"));
+ } /* end if */
+}
+#endif /* QAK */
+#ifdef QAK
+HDfprintf(stderr,"%s: adjust={",FUNC);
+for(u=0; u<fm->f_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",adjust[u],(u<(fm->f_ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
+
+ /* Iterate over each chunk in the file chunk list */
+ curr_node=H5TB_first(fm->fsel->root);
+ while(curr_node) {
+ H5D_fchunk_info_t *fchunk_info; /* Pointer to file chunk information */
+ H5D_mchunk_info_t *mchunk_info; /* Pointer to memory chunk information */
+
+ /* Get pointer to chunk's information */
+ fchunk_info=curr_node->data;
+ assert(fchunk_info);
+
+ /* Allocate space for the memory chunk information */
+ if (NULL==(mchunk_info = H5FL_MALLOC (H5D_mchunk_info_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate memory chunk info");
+
+ /* Copy the information */
+
+ /* Set the chunk index */
+ mchunk_info->index=fchunk_info->index;
+
+ /* Copy the memory dataspace */
+ if((mchunk_info->space = H5S_copy(fm->mem_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
+
+ /* Release the current selection */
+ if(H5S_select_release(mchunk_info->space)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection");
+
+ /* Copy the file chunk's selection */
+ if(H5S_select_copy(mchunk_info->space,fchunk_info->space)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection");
+
+ /* Compensate for the chunk offset */
+ for(u=0; u<fm->f_ndims; u++)
+ chunk_adjust[u]=adjust[u]-(fchunk_info->coords[u]*fm->layout->dim[u]);
+#ifdef QAK
+{
+ int mpi_rank;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ if(mpi_rank==1) {
+ HDfprintf(stderr,"%s: rank=%d - Before adjusting memory selection\n",FUNC,mpi_rank);
+ HDfprintf(stderr,"%s: rank=%d - chunk_adjust={",FUNC,mpi_rank);
+ for(u=0; u<fm->f_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_adjust[u],(u<(fm->f_ndims-1) ? ", " : "}\n"));
+ } /* end if */
+}
+#endif /* QAK */
+#ifdef QAK
+HDfprintf(stderr,"%s: Before adjusting memory selection\n",FUNC);
+HDfprintf(stderr,"%s: chunk_adjust={",FUNC);
+for(u=0; u<fm->f_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_adjust[u],(u<(fm->f_ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
+ /* Adjust the selection */
+ if(H5S_hyper_adjust(mchunk_info->space,chunk_adjust)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection");
+#ifdef QAK
+{
+ int mpi_rank;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ if(mpi_rank==1)
+ HDfprintf(stderr,"%s: rank=%d - After adjusting memory selection\n",FUNC,mpi_rank);
+}
+#endif /* QAK */
+#ifdef QAK
+HDfprintf(stderr,"%s: After adjusting memory selection\n",FUNC);
+
+{
+ hsize_t mem_dims[H5O_LAYOUT_NDIMS]; /* Dimensions of memory space */
+
+ if(H5S_get_simple_extent_dims(mchunk_info->space, mem_dims, NULL)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
+
+ HDfprintf(stderr,"%s: mem_dims={",FUNC);
+ for(u=0; u<fm->m_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",mem_dims[u],(u<(fm->m_ndims-1) ? ", " : "}\n"));
+}
+#endif /* QAK */
+ /* Insert the new memory chunk into the TBBT tree */
+ if(H5TB_dins(fm->msel,mchunk_info,mchunk_info)==NULL)
+ HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert memory chunk into TBBT");
+
+ /* Get the next chunk node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_create_chunk_mem_map() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_mem_cb
*
* Purpose: Callback routine for file selection iterator. Used when
- * creating selections in memory and each chunk for each chunk.
+ * creating selections in memory for each chunk.
*
* Return: Non-negative on success/Negative on failure
*
@@ -2533,54 +2973,26 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_chunk_cb(void UNUSED *elem, hid_t UNUSED type_id, hsize_t ndims, hssize_t *coords, void *_fm)
+H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, hsize_t ndims, hssize_t *coords, void *_fm)
{
fm_map *fm = (fm_map*)_fm; /* File<->memory chunk mapping info */
- H5S_t *fspace; /* File chunk's dataspace */
H5S_t *mspace; /* Memory chunk's dataspace */
- hssize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
hssize_t coords_in_mem[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */
hsize_t chunk_index; /* Chunk index */
hsize_t u; /* Local index variables */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOINIT(H5D_chunk_cb);
-#ifdef QAK
-{
- unsigned u;
- HDfprintf(stderr,"%s: coords={",FUNC);
- for(u=0; u<ndims; u++)
- HDfprintf(stderr,"%Hd%s",coords[u],(u<(ndims-1)?", ":"}\n"));
-}
-#endif /* QAK */
+ FUNC_ENTER_NOINIT(H5D_chunk_mem_cb);
/* Calculate the index of this chunk */
if(H5V_chunk_index((unsigned)ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index");
-#ifdef QAK
-HDfprintf(stderr,"%s: chunk_index=%Hu\n",FUNC,chunk_index);
-#endif /* QAK */
-
- /*convert coords from relative to whole file space to relative to its chunk space,
- *pass into H5S_select_hyperslab.*/
- for(u=0; u<ndims; u++)
- coords_in_chunk[u] = coords[u] % fm->layout->dim[u];
-
-#ifdef QAK
-{
- unsigned u;
- HDfprintf(stderr,"%s: coords_in_chunk={",FUNC);
- for(u=0; u<ndims; u++)
- HDfprintf(stderr,"%Hd%s",coords_in_chunk[u],(u<(ndims-1)?", ":"}\n"));
-}
-#endif /* QAK */
/* Find correct chunk in file & memory TBBTs */
if(chunk_index==fm->last_index) {
/* If the chunk index is the same as the last chunk index we used,
* get the cached spaces to operate on.
*/
- fspace=fm->last_fchunk;
mspace=fm->last_mchunk;
} /* end if */
else {
@@ -2589,48 +3001,22 @@ HDfprintf(stderr,"%s: chunk_index=%Hu\n",FUNC,chunk_index);
* find the chunk in the tree.
*/
/* Get the chunk node from the TBBT */
- if((chunk_node=H5TB_dfind(fm->fsel,&chunk_index,NULL))!=NULL) {
+ if((chunk_node=H5TB_dfind(fm->msel,&chunk_index,NULL))!=NULL) {
/* We found the correct chunk already in the tree */
- /* Get the file space information from the node */
- fspace=((H5D_fchunk_info_t *)(chunk_node->data))->space;
-
- /* Look up the memory space information for the chunk */
- if((chunk_node=H5TB_dfind(fm->msel,&chunk_index,NULL))==NULL)
- HGOTO_ERROR (H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't find memory chunk info");
-
- /* Get the file space information from the node */
+ /* Get the memory space information from the node */
mspace=((H5D_mchunk_info_t *)(chunk_node->data))->space;
} /* end if */
else {
- H5D_fchunk_info_t *new_fchunk_info; /* File chunk information to insert into tree */
H5D_mchunk_info_t *new_mchunk_info; /* Memory chunk information to insert into tree */
/* The correct chunk is not already in the tree, create a new node */
/* in both the file and memory chunk trees */
- /* Allocate the file & memory chunk information */
- if (NULL==(new_fchunk_info = H5FL_MALLOC (H5D_fchunk_info_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate file chunk info");
+ /* Allocate the memory chunk information */
if (NULL==(new_mchunk_info = H5FL_MALLOC (H5D_mchunk_info_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate memory chunk info");
- /* Initialize the file chunk information */
-
- /* Set the chunk index */
- new_fchunk_info->index=chunk_index;
-
- /* Copy the template file chunk dataspace */
- if((new_fchunk_info->space = H5S_copy(fm->fchunk_tmpl))==NULL)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space");
-
- /* Compute the chunk's coordinates */
- H5D_chunk_coords_assist(new_fchunk_info->coords, fm->f_ndims, fm->chunks, chunk_index);
-
- /* Insert the new file chunk into the TBBT tree */
- if(H5TB_dins(fm->fsel,new_fchunk_info,new_fchunk_info)==NULL)
- HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert file chunk into TBBT");
-
/* Initialize the memory chunk information */
/* Set the chunk index */
@@ -2645,32 +3031,18 @@ HDfprintf(stderr,"%s: chunk_index=%Hu\n",FUNC,chunk_index);
HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert memory chunk into TBBT");
/* Get the dataspaces for use in this routine */
- fspace=new_fchunk_info->space;
mspace=new_mchunk_info->space;
} /* end else */
/* Update the "last chunk seen" information */
fm->last_index=chunk_index;
- fm->last_fchunk=fspace;
fm->last_mchunk=mspace;
} /* end else */
- /* Add point to file selection for chunk */
- if(H5S_hyper_add_span_element(fspace, fm->f_ndims, coords_in_chunk)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element");
-
/* Get coordinates of selection iterator for memory */
if(H5S_select_iter_coords(&fm->mem_iter,coords_in_mem)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator coordinates");
-#ifdef QAK
-{
- unsigned u;
- HDfprintf(stderr,"%s: coords_in_mem={",FUNC);
- for(u=0; u<fm->m_ndims; u++)
- HDfprintf(stderr,"%Hd%s",coords_in_mem[u],(u<(fm->m_ndims-1)?", ":"}\n"));
-}
-#endif /* QAK */
/* Add point to memory selection for chunk */
if(H5S_hyper_add_span_element(mspace, fm->m_ndims, coords_in_mem)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element");
@@ -2681,4 +3053,4 @@ HDfprintf(stderr,"%s: chunk_index=%Hu\n",FUNC,chunk_index);
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5D_chunk_cb() */
+} /* end H5D_chunk_mem_cb() */
diff --git a/src/H5Distore.c b/src/H5Distore.c
index a5362cc..ffbc6de 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -1743,7 +1743,19 @@ H5F_istore_readvv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
/* Get the address of this chunk on disk */
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_coords_in_elmts={",FUNC);
+for(u=0; u<layout->ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_coords_in_elmts[u],(u<(layout->ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,chunk_size);
+HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
+HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_arr[*mem_curr_seq]);
+#endif /* QAK */
/*
* If the chunk is too large to load into the cache and it has no
@@ -1850,7 +1862,19 @@ H5F_istore_writevv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
/* Get the address of this chunk on disk */
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_coords_in_elmts={",FUNC);
+for(u=0; u<layout->ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_coords_in_elmts[u],(u<(layout->ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,chunk_size);
+HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
+HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_arr[*mem_curr_seq]);
+#endif /* QAK */
/*
* If the chunk is too large to load into the cache and it has no
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index a5362cc..ffbc6de 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -1743,7 +1743,19 @@ H5F_istore_readvv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
/* Get the address of this chunk on disk */
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_coords_in_elmts={",FUNC);
+for(u=0; u<layout->ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_coords_in_elmts[u],(u<(layout->ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,chunk_size);
+HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
+HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_arr[*mem_curr_seq]);
+#endif /* QAK */
/*
* If the chunk is too large to load into the cache and it has no
@@ -1850,7 +1862,19 @@ H5F_istore_writevv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
/* Get the address of this chunk on disk */
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_coords_in_elmts={",FUNC);
+for(u=0; u<layout->ndims; u++)
+ HDfprintf(stderr,"%Hd%s",chunk_coords_in_elmts[u],(u<(layout->ndims-1) ? ", " : "}\n"));
+#endif /* QAK */
chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,chunk_size);
+HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
+HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
+HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_arr[*mem_curr_seq]);
+#endif /* QAK */
/*
* If the chunk is too large to load into the cache and it has no
diff --git a/src/H5S.c b/src/H5S.c
index 61b2b04..f69f8f5 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -454,12 +454,8 @@ H5S_close(H5S_t *ds)
assert(ds);
- /* If there was a previous offset for the selection, release it */
- if(ds->select.offset!=NULL)
- ds->select.offset=H5FL_ARR_FREE(hssize_t,ds->select.offset);
-
/* Release selection (this should come before the extent release) */
- (*ds->select.release)(ds);
+ H5S_select_release(ds);
/* Release extent */
H5S_extent_release(ds);
@@ -1913,14 +1909,9 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset)
if (offset == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no offset specified");
- /* Allocate space for new offset */
- if(space->select.offset==NULL) {
- if (NULL==(space->select.offset = H5FL_ARR_MALLOC(hssize_t,space->extent.u.simple.rank)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- }
-
- /* Copy the offset over */
- HDmemcpy(space->select.offset,offset,sizeof(hssize_t)*space->extent.u.simple.rank);
+ /* Set the selection offset */
+ if(H5S_select_offset(space,offset)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset");
done:
FUNC_LEAVE_API(ret_value);
@@ -1964,16 +1955,8 @@ H5S_set_extent( H5S_t *space, const hsize_t *size )
} /* end for */
/* Update */
- if (ret_value) {
- hsize_t nelem; /* Number of elements in extent */
-
- /* Change the dataspace size & re-compute the number of elements in the extent */
- for (u=0, nelem=1; u < space->extent.u.simple.rank; u++ ) {
- space->extent.u.simple.size[u] = size[u];
- nelem*=space->extent.u.simple.size[u];
- } /* end for */
- space->extent.nelem = nelem;
- } /* end if */
+ if (ret_value)
+ H5S_set_extent_real(space,size);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1981,6 +1964,46 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5S_set_extent_real
+ *
+ * Purpose: Modify the dimensions of a data space. Based on H5S_extend
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: March 13, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_set_extent_real( H5S_t *space, const hsize_t *size )
+{
+ hsize_t nelem; /* Number of elements in extent */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_set_extent_real, FAIL );
+
+ /* Check args */
+ assert(space && H5S_SIMPLE==space->extent.type );
+ assert(size);
+
+ /* Change the dataspace size & re-compute the number of elements in the extent */
+ for (u=0, nelem=1; u < space->extent.u.simple.rank; u++ ) {
+ space->extent.u.simple.size[u] = size[u];
+ nelem*=space->extent.u.simple.size[u];
+ } /* end for */
+ space->extent.nelem = nelem;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5S_set_extent_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_debug
*
* Purpose: Prints debugging information about a data space.
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 0687251..e62dc4f 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -1783,8 +1783,14 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
UINT32ENCODE(buf, (uint32_t)offset[i]);
/* Encode hyperslab ending location */
- for(i=0; i<ndims; i++)
- UINT32ENCODE(buf, (uint32_t)(offset[i]+(diminfo[i].block-1)));
+ for(i=0; i<ndims; i++) {
+ if(diminfo[i].stride==1) {
+ UINT32ENCODE(buf, (uint32_t)(offset[i]+(diminfo[i].count-1)));
+ } /* end if */
+ else {
+ UINT32ENCODE(buf, (uint32_t)(offset[i]+(diminfo[i].block-1)));
+ } /* end else */
+ } /* end for */
/* Move the offset to the next sequence to start */
offset[fast_dim]+=diminfo[fast_dim].stride;
@@ -1878,10 +1884,12 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
size_t num_elem=0; /* number of elements in selection */
hssize_t *start=NULL; /* hyperslab start information */
hssize_t *end=NULL; /* hyperslab end information */
+ hsize_t *stride=NULL; /* hyperslab stride information */
hsize_t *count=NULL; /* hyperslab count information */
hsize_t *block=NULL; /* hyperslab block information */
hssize_t *tstart=NULL; /* temporary hyperslab pointers */
hssize_t *tend=NULL; /* temporary hyperslab pointers */
+ hsize_t *tstride=NULL; /* temporary hyperslab pointers */
hsize_t *tcount=NULL; /* temporary hyperslab pointers */
hsize_t *tblock=NULL; /* temporary hyperslab pointers */
unsigned i,j; /* local counting variables */
@@ -1909,10 +1917,14 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
if((count = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
+ if((stride = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- /* Set the count for all blocks */
- for(tcount=count,j=0; j<rank; j++,tcount++)
+ /* Set the count & stride for all blocks */
+ for(tcount=count,tstride=stride,j=0; j<rank; j++,tstride++,tcount++) {
*tcount=1;
+ *tstride=0;
+ } /* end for */
/* Retrieve the coordinates from the buffer */
for(i=0; i<num_elem; i++) {
@@ -1929,13 +1941,14 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
*tblock=(*tend-*tstart)+1;
/* Select or add the hyperslab to the current selection */
- if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,NULL,count,block))<0)
+ if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
} /* end for */
/* Free temporary buffers */
H5FL_ARR_FREE(hsize_t,start);
H5FL_ARR_FREE(hsize_t,end);
+ H5FL_ARR_FREE(hsize_t,stride);
H5FL_ARR_FREE(hsize_t,count);
H5FL_ARR_FREE(hsize_t,block);
@@ -2078,7 +2091,7 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static herr_t
+herr_t
H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
{
H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
@@ -2132,8 +2145,12 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numbloc
/* Compute the ending location */
HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
- for(i=0; i<ndims; i++)
- buf[i]+=(diminfo[i].block-1);
+ for(i=0; i<ndims; i++) {
+ if(diminfo[i].stride==1)
+ buf[i]+=(diminfo[i].count-1);
+ else
+ buf[i]+=(diminfo[i].block-1);
+ } /* end for */
buf+=ndims;
/* Decrement the number of blocks to retrieve */
@@ -3174,6 +3191,423 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_hyper_convert
+ PURPOSE
+ Convert a compatible selection to span tree form
+ USAGE
+ herr_t H5S_hyper_convert(space)
+ H5S_t *space; IN/OUT: Pointer to dataspace to convert
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Converts a compatible selection (currently only "all" selections) to the
+ span-tree form of a hyperslab selection. (Point and "none" selection aren't
+ currently supported and hyperslab selection always have the span-tree form
+ available).
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_convert(H5S_t *space)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_convert);
+
+ assert(space);
+
+ /* Check the type of selection */
+ switch(space->select.type) {
+ case H5S_SEL_ALL: /* All elements selected in dataspace */
+ /* Convert current "all" selection to "real" hyperslab selection */
+ {
+ hssize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */
+ hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */
+ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */
+ unsigned u; /* Local index variable */
+
+ /* Fill in temporary information for the dimensions */
+ for(u=0; u<space->extent.u.simple.rank; u++) {
+ tmp_start[u]=0;
+ tmp_stride[u]=0;
+ tmp_count[u]=1;
+ tmp_block[u]=space->extent.u.simple.size[u];
+ } /* end for */
+
+ /* Convert to hyperslab selection */
+ if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection");
+ } /* end case */
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection */
+ break;
+
+ case H5S_SEL_NONE: /* No elements selected in dataspace */
+ case H5S_SEL_POINTS: /* Point selection */
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "can't convert to span tree selection");
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_convert() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect_helper
+ PURPOSE
+ Helper routine to detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect_helper(spans1, spans2)
+ H5S_hyper_span_info_t *spans1; IN: First span tree to operate with
+ H5S_hyper_span_info_t *spans2; IN: Second span tree to operate with
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between two span trees
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static htri_t
+H5S_hyper_intersect_helper (H5S_hyper_span_info_t *spans1, H5S_hyper_span_info_t *spans2)
+{
+ H5S_hyper_span_t *curr1; /* Pointer to current span in 1st span tree */
+ H5S_hyper_span_t *curr2; /* Pointer to current span in 2nd span tree */
+ htri_t status; /* Status from recursive call */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_intersect_helper);
+
+ /* Sanity check */
+ assert((spans1 && spans2) || (spans1==NULL && spans2==NULL));
+
+ /* "NULL" span trees compare as overlapping */
+ if(spans1==NULL && spans2==NULL)
+ HGOTO_DONE(TRUE);
+
+ /* Get the span lists for each span in this tree */
+ curr1=spans1->head;
+ curr2=spans2->head;
+
+ /* Iterate over the spans in each tree */
+ while(curr1!=NULL && curr2!=NULL) {
+ /* Check for 1st span entirely before 2nd span */
+ if(curr1->high<curr2->low)
+ curr1=curr1->next;
+ /* Check for 2nd span entirely before 1st span */
+ else if(curr2->high<curr1->low)
+ curr2=curr2->next;
+ /* Spans must overlap */
+ else {
+ /* Recursively check spans in next dimension down */
+ if((status=H5S_hyper_intersect_helper(curr1->down,curr2->down))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
+
+ /* If there is a span intersection in the down dimensions, the span trees overlap */
+ if(status==TRUE)
+ HGOTO_DONE(TRUE);
+
+ /* No intersection in down dimensions, advance to next span */
+ if(curr1->high<curr2->high)
+ curr1=curr1->next;
+ else
+ curr2=curr2->next;
+ } /* end else */
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_intersect_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect
+ PURPOSE
+ Detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect_helper(space1, space2)
+ H5S_t *space1; IN: First dataspace to operate on span tree
+ H5S_t *space2; IN: Second dataspace to operate on span tree
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between two span trees
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_hyper_intersect (H5S_t *space1, H5S_t *space2)
+{
+ htri_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_intersect);
+
+ /* Sanity check */
+ assert(space1);
+ assert(space2);
+
+ /* Check that the space selections both have span trees */
+ if(space1->select.sel_info.hslab.span_lst==NULL ||
+ space2->select.sel_info.hslab.span_lst==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_ARGS, FAIL, "dataspace does not have span tree");
+
+ /* Check that the dataspaces are both the same rank */
+ if(space1->extent.u.simple.rank!=space2->extent.u.simple.rank)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_ARGS, FAIL, "dataspace ranks don't match");
+
+ /* Perform the span-by-span intersection check */
+ if((ret_value=H5S_hyper_intersect_helper(space1->select.sel_info.hslab.span_lst,space2->select.sel_info.hslab.span_lst))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_intersect() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_adjust_helper
+ PURPOSE
+ Helper routine to adjust offsets in span trees
+ USAGE
+ herr_t H5S_hyper_adjust_helper(spans, offset)
+ H5S_hyper_span_info_t *spans; IN: Span tree to operate with
+ const hssize_t *offset; IN: Offset to subtract
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Adjust the location of the spans in a span tree by subtracting an offset
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_adjust_helper (H5S_hyper_span_info_t *spans, const hssize_t *offset)
+{
+ H5S_hyper_span_t *span; /* Pointer to current span in span tree */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_adjust_helper);
+
+ /* Sanity check */
+ assert(spans);
+ assert(offset);
+
+ /* Check if we've already set this down span tree */
+ if(spans->scratch!=(H5S_hyper_span_info_t *)~((size_t)NULL)) {
+ /* Set the tree's scratch pointer */
+ spans->scratch=(H5S_hyper_span_info_t *)~((size_t)NULL);
+
+ /* Get the span lists for each span in this tree */
+ span=spans->head;
+
+ /* Iterate over the spans in tree */
+ while(span!=NULL) {
+#ifdef QAK
+HDfprintf(stderr,"%s: span={%Hd, %Hd}, *offset=%Hd\n",FUNC,span->low,span->high,*offset);
+#endif /* QAK */
+ /* Adjust span offset */
+ span->low-=*offset;
+ assert(span->low>=0);
+ span->high-=*offset;
+ assert(span->high>=0);
+
+ /* Recursively adjust spans in next dimension down */
+ if(span->down!=NULL) {
+ if(H5S_hyper_adjust_helper(span->down,offset+1)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab adjustment");
+ } /* end if */
+
+ /* Advance to next span in this dimension */
+ span=span->next;
+ } /* end while */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_adjust_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_adjust
+ PURPOSE
+ Adjust a hyperslab selection by subtracting an offset
+ USAGE
+ herr_t H5S_hyper_adjust(space,offset)
+ H5S_t *space; IN/OUT: Pointer to dataspace to adjust
+ const hssize_t *offset; IN: Offset to subtract
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Moves a hyperslab selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_adjust(H5S_t *space, const hssize_t *offset)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_adjust);
+
+ assert(space);
+ assert(offset);
+
+ /* Subtract the offset from the "regular" coordinates, if they exist */
+ if(space->select.sel_info.hslab.diminfo) {
+ for(u=0; u<space->extent.u.simple.rank; u++) {
+ space->select.sel_info.hslab.diminfo[u].start-=offset[u];
+ assert(space->select.sel_info.hslab.diminfo[u].start>=0);
+ } /* end for */
+ } /* end if */
+
+ /* Subtract the offset from the span tree coordinates, if they exist */
+ if(space->select.sel_info.hslab.span_lst) {
+ if(H5S_hyper_adjust_helper(space->select.sel_info.hslab.span_lst,offset)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset adjustment");
+
+ /* Reset the scratch pointers for the next routine which needs them */
+ if(H5S_hyper_span_scratch(space->select.sel_info.hslab.span_lst,NULL)==FAIL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_adjust() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_move_helper
+ PURPOSE
+ Helper routine to move offset in span trees
+ USAGE
+ herr_t H5S_hyper_move_helper(spans, offset)
+ H5S_hyper_span_info_t *spans; IN: Span tree to operate with
+ const hssize_t *offset; IN: Offset to move to
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Adjust the location of the spans in a span tree by moving selection to an
+ offset.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_move_helper (H5S_hyper_span_info_t *spans, const hssize_t *offset)
+{
+ H5S_hyper_span_t *span; /* Pointer to current span in span tree */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_move_helper);
+
+ /* Sanity check */
+ assert(spans);
+ assert(offset);
+
+ /* Check if we've already set this down span tree */
+ if(spans->scratch!=(H5S_hyper_span_info_t *)~((size_t)NULL)) {
+ /* Set the tree's scratch pointer */
+ spans->scratch=(H5S_hyper_span_info_t *)~((size_t)NULL);
+
+ /* Get the span lists for each span in this tree */
+ span=spans->head;
+
+ /* Iterate over the spans in tree */
+ while(span!=NULL) {
+ /* Adjust span location */
+ span->high=*offset+(span->high-span->low);
+ assert(span->high>=0);
+ span->low=*offset;
+ assert(span->low>=0);
+
+ /* Recursively move spans in next dimension down */
+ if(span->down!=NULL) {
+ if(H5S_hyper_move_helper(span->down,offset+1)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab movement");
+ } /* end if */
+
+ /* Advance to next span in this dimension */
+ span=span->next;
+ } /* end while */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_move_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_move
+ PURPOSE
+ Move a hyperslab selection by to an offset
+ USAGE
+ herr_t H5S_hyper_move(space,offset)
+ H5S_t *space; IN/OUT: Pointer to dataspace to move
+ const hssize_t *offset; IN: Offset to move to
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Moves a hyperslab selection to a new offset.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_move(H5S_t *space, const hssize_t *offset)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_move);
+
+ assert(space);
+ assert(offset);
+
+ /* Move to the offset with the "regular" coordinates, if they exist */
+ if(space->select.sel_info.hslab.diminfo) {
+ for(u=0; u<space->extent.u.simple.rank; u++) {
+ space->select.sel_info.hslab.diminfo[u].start=offset[u];
+ assert(space->select.sel_info.hslab.diminfo[u].start>=0);
+ } /* end for */
+ } /* end if */
+
+ /* Subtract the offset from the span tree coordinates, if they exist */
+ if(space->select.sel_info.hslab.span_lst) {
+ if(H5S_hyper_move_helper(space->select.sel_info.hslab.span_lst,offset)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset movement");
+
+ /* Reset the scratch pointers for the next routine which needs them */
+ if(H5S_hyper_span_scratch(space->select.sel_info.hslab.span_lst,NULL)==FAIL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_move() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_append_span
PURPOSE
Create a new span and append to span list
@@ -5158,7 +5592,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
/* Fill in temporary information for the dimensions */
for(u=0; u<space->extent.u.simple.rank; u++) {
tmp_start[u]=0;
- tmp_stride[u]=1;
+ tmp_stride[u]=0;
tmp_count[u]=1;
tmp_block[u]=space->extent.u.simple.size[u];
} /* end for */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 5792e67..4e6eda7 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -168,6 +168,7 @@ H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, const H5S_t
H5_DLL H5S_t *H5S_read(struct H5G_entry_t *ent, hid_t dxpl_id);
H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size);
H5_DLL int H5S_set_extent(H5S_t *space, const hsize_t *size);
+H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size);
H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/],
const hsize_t maxdims[/*rank*/]);
H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream,
@@ -204,14 +205,22 @@ H5_DLL herr_t H5S_select_write(H5F_t *f, struct H5O_layout_t *layout,
const void *buf/*out*/);
H5_DLL htri_t H5S_select_valid(const H5S_t *space);
H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space);
+H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
+H5_DLL herr_t H5S_select_release(H5S_t *ds);
H5_DLL herr_t H5S_select_all(H5S_t *space, unsigned rel_prev);
H5_DLL herr_t H5S_select_none(H5S_t *space);
H5_DLL herr_t H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hssize_t start[],
- const hsize_t *stride, const hsize_t count[],
- const hsize_t *block);
+ const hsize_t *stride, const hsize_t count[], const hsize_t *block);
+H5_DLL herr_t H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock,
+ hsize_t numblocks, hsize_t *buf);
H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank,
hssize_t *coords);
H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space);
+H5_DLL herr_t H5S_hyper_convert(H5S_t *space);
+H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2);
+H5_DLL herr_t H5S_hyper_adjust(H5S_t *space, const hssize_t *offset);
+H5_DLL herr_t H5S_hyper_move(H5S_t *space, const hssize_t *offset);
/* Operations on selection iterators */
H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 5551412..6c3d42d 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -92,6 +92,50 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_select_offset
+ PURPOSE
+ Set the selection offset for a datapace
+ USAGE
+ herr_t H5S_select_offset(space, offset)
+ H5S_t *space; IN/OUT: Dataspace object to set selection offset
+ const hssize_t *offset; IN: Offset to position the selection at
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Sets the selection offset for the dataspace
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Only works for simple dataspaces currently
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_offset(H5S_t *space, const hssize_t *offset)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_offset, FAIL);
+
+ /* Check args */
+ assert(space);
+ assert(offset);
+
+ /* Allocate space for new offset */
+ if(space->select.offset==NULL) {
+ if (NULL==(space->select.offset = H5FL_ARR_MALLOC(hssize_t,space->extent.u.simple.rank)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ }
+
+ /* Copy the offset over */
+ HDmemcpy(space->select.offset,offset,sizeof(hssize_t)*space->extent.u.simple.rank);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_copy
PURPOSE
Copy a selection from one dataspace to another
@@ -173,6 +217,41 @@ done:
} /* H5S_select_copy() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_select_release
+ *
+ * Purpose: Releases all memory associated with a dataspace selection.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 30, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_select_release(H5S_t *ds)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_release, FAIL);
+
+ assert(ds);
+
+ /* If there was a previous offset for the selection, release it */
+ if(ds->select.offset!=NULL)
+ ds->select.offset=H5FL_ARR_FREE(hssize_t,ds->select.offset);
+
+ /* Call the selection type's release function */
+ (*ds->select.release)(ds);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5S_select_release() */
+
+
/*--------------------------------------------------------------------------
NAME
H5Sget_select_npoints
@@ -423,7 +502,7 @@ H5Sget_select_bounds(hid_t spaceid, hsize_t *start, hsize_t *end)
if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- ret_value = (*space->select.bounds)(space,start,end);
+ ret_value = H5S_get_select_bounds(space,start,end);
done:
FUNC_LEAVE_API(ret_value);
@@ -432,6 +511,52 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_get_select_bounds
+ PURPOSE
+ Gets the bounding box containing the selection.
+ USAGE
+ herr_t H5S_get_select_bounds(space, start, end)
+ H5S_t *space; IN: Dataspace ID of selection to query
+ hsize_t *start; OUT: Starting coordinate of bounding box
+ hsize_t *end; OUT: Opposite coordinate of bounding box
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the bounding box containing the current selection and places
+ it into the user's buffers. The start and end buffers must be large
+ enough to hold the dataspace rank number of coordinates. The bounding box
+ exactly contains the selection, ie. if a 2-D element selection is currently
+ defined with the following points: (4,5), (6,8) (10,7), the bounding box
+ with be (4, 5), (10, 8). Calling this function on a "none" selection
+ returns fail.
+ The bounding box calculations _does_ include the current offset of the
+ selection within the dataspace extent.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
+{
+ herr_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_get_select_bounds, FAIL);
+
+ /* Check args */
+ assert(space);
+ assert(start);
+ assert(end);
+
+ ret_value = (*space->select.bounds)(space,start,end);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_get_select_bounds() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_iter_init
PURPOSE
Initializes iteration information for a selection.
@@ -1578,6 +1703,12 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
curr_mem_seq=0;
} /* end if */
+#ifdef QAK
+HDfprintf(stderr,"%s: curr_file_seq=%Zu, file_nseq=%Zu\n",FUNC,curr_file_seq,file_nseq);
+HDfprintf(stderr,"%s: curr_mem_seq=%Zu, mem_nseq=%Zu\n",FUNC,curr_mem_seq,mem_nseq);
+HDfprintf(stderr,"%s: file_off[%Zu]=%Hu, file_len[%Zu]=%Zu\n",FUNC,curr_file_seq,file_off[curr_file_seq],curr_file_seq,file_len[curr_file_seq]);
+HDfprintf(stderr,"%s: mem_off[%Zu]=%Hu, mem_len[%Zu]=%Zu\n",FUNC,curr_mem_seq,mem_off[curr_mem_seq],curr_mem_seq,mem_len[curr_mem_seq]);
+#endif /* QAK */
/* Read file sequences into current memory sequence */
if ((tmp_file_len=H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store,
file_nseq, &curr_file_seq, file_len, file_off,
@@ -1654,6 +1785,15 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_write, FAIL);
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Entering, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
/* Check args */
assert(f);
@@ -1721,6 +1861,31 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
curr_mem_seq=0;
} /* end if */
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - time=%f\n",FUNC,mpi_rank,time);
+ HDfprintf(stderr,"%s: rank=%d - curr_file_seq=%Zu, file_nseq=%Zu\n",FUNC,mpi_rank,curr_file_seq,file_nseq);
+ HDfprintf(stderr,"%s: rank=%d - curr_mem_seq=%Zu, mem_nseq=%Zu\n",FUNC,mpi_rank,curr_mem_seq,mem_nseq);
+ HDfprintf(stderr,"%s: rank=%d - file_off[%Zu]=%Hu, file_len[%Zu]=%Zu\n",FUNC,mpi_rank,curr_file_seq,file_off[curr_file_seq],curr_file_seq,file_len[curr_file_seq]);
+ HDfprintf(stderr,"%s: rank=%d - mem_off[%Zu]=%Hu, mem_len[%Zu]=%Zu\n",FUNC,mpi_rank,curr_mem_seq,mem_off[curr_mem_seq],curr_mem_seq,mem_len[curr_mem_seq]);
+}
+#endif /* QAK */
+#ifdef QAK
+{
+ unsigned u;
+
+HDfprintf(stderr,"%s: curr_file_seq=%Zu, file_nseq=%Zu\n",FUNC,curr_file_seq,file_nseq);
+HDfprintf(stderr,"%s: curr_mem_seq=%Zu, mem_nseq=%Zu\n",FUNC,curr_mem_seq,mem_nseq);
+for(u=curr_file_seq; u<file_nseq; u++)
+ HDfprintf(stderr,"%s: file_off[%u]=%Hu, file_len[%u]=%Zu\n",FUNC,u,file_off[u],u,file_len[u]);
+for(u=curr_mem_seq; u<mem_nseq; u++)
+ HDfprintf(stderr,"%s: mem_off[%u]=%Hu, mem_len[%u]=%Zu\n",FUNC,u,mem_off[u],u,mem_len[u]);
+}
+#endif /* QAK */
/* Write memory sequences into file sequences */
if ((tmp_file_len=H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store,
file_nseq, &curr_file_seq, file_len, file_off,
@@ -1754,6 +1919,15 @@ done:
H5FL_ARR_FREE(size_t,mem_len);
if(mem_off!=NULL)
H5FL_ARR_FREE(hsize_t,mem_off);
+#ifdef QAK
+{
+ int mpi_rank;
+ double time;
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ time = MPI_Wtime();
+ HDfprintf(stderr,"%s: rank=%d - Leaving, time=%f\n",FUNC,mpi_rank,time);
+}
+#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5S_select_write() */