summaryrefslogtreecommitdiffstats
path: root/src/H5Dio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dio.c')
-rw-r--r--src/H5Dio.c650
1 files changed, 511 insertions, 139 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() */