diff options
-rw-r--r-- | src/H5Dio.c | 650 | ||||
-rw-r--r-- | src/H5Distore.c | 24 | ||||
-rw-r--r-- | src/H5Fistore.c | 24 | ||||
-rw-r--r-- | src/H5S.c | 69 | ||||
-rw-r--r-- | src/H5Shyper.c | 452 | ||||
-rw-r--r-- | src/H5Sprivate.h | 13 | ||||
-rw-r--r-- | src/H5Sselect.c | 176 |
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 @@ -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() */ |