mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-11 16:01:00 +08:00
[svn-r14307] Description:
- Extracted common code from H5D_select_read/H5D_select_write into single routine (H5D_select_io) and made H5D_select_read/H5D_select_write "gateway" routines, passing I/O buffer to operate on in "op" struct. - Create optimized pathway in H5D_select_io for I/O operations on single elements. - Make "get linear offset of first element" callback for each type of selection (used in "optimized pathway", above) Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
This commit is contained in:
parent
44fa94541b
commit
765f0159ff
456
src/H5Dselect.c
456
src/H5Dselect.c
@ -46,6 +46,18 @@
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
|
||||
/* Struct for holding the vectorized I/O operation buffers "loosely" */
|
||||
typedef struct {
|
||||
enum {
|
||||
H5S_SELECT_READ, /* Read selection */
|
||||
H5S_SELECT_WRITE /* Write selection */
|
||||
} op_type;
|
||||
union {
|
||||
void *rbuf; /* Buffer for read */
|
||||
const void *wbuf; /* Buffer to write */
|
||||
} u;
|
||||
} H5D_select_buf_t;
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
/*********************/
|
||||
@ -417,6 +429,196 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5D_select_mgath() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D_select_io
|
||||
*
|
||||
* Purpose: Perform I/O directly from application memory and a file
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, November 27, 2007
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D_select_io(H5D_io_info_t *io_info,
|
||||
size_t nelmts, size_t elmt_size,
|
||||
const H5S_t *file_space, const H5S_t *mem_space,
|
||||
haddr_t addr, void *chunk/*in*/,
|
||||
const H5D_select_buf_t *io_buf)
|
||||
{
|
||||
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
|
||||
hbool_t mem_iter_init = 0; /* Memory selection iteration info has been initialized */
|
||||
H5S_sel_iter_t file_iter; /* File selection iteration info */
|
||||
hbool_t file_iter_init = 0; /* File selection iteration info has been initialized */
|
||||
hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
|
||||
hsize_t *mem_off = NULL; /* Pointer to sequence offsets in memory */
|
||||
hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */
|
||||
hsize_t *file_off = NULL; /* Pointer to sequence offsets in the file */
|
||||
size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
|
||||
size_t *mem_len = NULL; /* Pointer to sequence lengths in memory */
|
||||
size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */
|
||||
size_t *file_len = NULL; /* Pointer to sequence lengths in the file */
|
||||
size_t curr_mem_seq; /* Current memory sequence to operate on */
|
||||
size_t curr_file_seq; /* Current file sequence to operate on */
|
||||
size_t mem_nseq; /* Number of sequences generated in the file */
|
||||
size_t file_nseq; /* Number of sequences generated in memory */
|
||||
ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5D_select_io, FAIL)
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->dset);
|
||||
HDassert(io_info->store);
|
||||
HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER));
|
||||
HDassert(io_buf->u.rbuf);
|
||||
|
||||
/* Allocate the vector I/O arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if(NULL == (mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
|
||||
if(NULL == (mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
|
||||
if(NULL == (file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
|
||||
if(NULL == (file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
|
||||
} /* end if */
|
||||
else {
|
||||
mem_len = _mem_len;
|
||||
mem_off = _mem_off;
|
||||
file_len = _file_len;
|
||||
file_off = _file_off;
|
||||
} /* end else */
|
||||
|
||||
/* Check for only one element in selection */
|
||||
if(nelmts == 1) {
|
||||
/* Get offset of first element in selections */
|
||||
if(H5S_SELECT_OFFSET(file_space, file_off) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve file selection offset")
|
||||
if(H5S_SELECT_OFFSET(mem_space, mem_off) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve memory selection offset")
|
||||
|
||||
/* Set up necessary information for I/O operation */
|
||||
file_nseq = mem_nseq = 1;
|
||||
curr_mem_seq = curr_file_seq = 0;
|
||||
*file_off *= elmt_size;
|
||||
*mem_off *= elmt_size;
|
||||
*file_len = *mem_len = elmt_size;
|
||||
|
||||
/* Perform I/O on memory and file sequences */
|
||||
if(io_buf->op_type == H5S_SELECT_READ) {
|
||||
if((tmp_file_len = (*io_info->ops.readvv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, io_buf->u.rbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
} /* end if */
|
||||
else {
|
||||
HDassert(io_buf->op_type == H5S_SELECT_WRITE);
|
||||
if((tmp_file_len = (*io_info->ops.writevv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, io_buf->u.wbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
} /* end else */
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
HDassert((tmp_file_len % elmt_size) == 0);
|
||||
} /* end if */
|
||||
else {
|
||||
size_t mem_nelem; /* Number of elements used in memory sequences */
|
||||
size_t file_nelem; /* Number of elements used in file sequences */
|
||||
|
||||
/* Initialize file iterator */
|
||||
if(H5S_select_iter_init(&file_iter, file_space, elmt_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
||||
file_iter_init = 1; /* File selection iteration info has been initialized */
|
||||
|
||||
/* Initialize memory iterator */
|
||||
if(H5S_select_iter_init(&mem_iter, mem_space, elmt_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
||||
mem_iter_init = 1; /* Memory selection iteration info has been initialized */
|
||||
|
||||
/* Initialize sequence counts */
|
||||
curr_mem_seq = curr_file_seq = 0;
|
||||
mem_nseq = file_nseq = 0;
|
||||
|
||||
/* Loop, until all bytes are processed */
|
||||
while(nelmts > 0) {
|
||||
/* Check if more file sequences are needed */
|
||||
if(curr_file_seq >= file_nseq) {
|
||||
/* Get sequences for file selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(file_space, H5S_GET_SEQ_LIST_SORTED, &file_iter, io_info->dxpl_cache->vec_size, nelmts, &file_nseq, &file_nelem, file_off, file_len) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_file_seq = 0;
|
||||
} /* end if */
|
||||
|
||||
/* Check if more memory sequences are needed */
|
||||
if(curr_mem_seq >= mem_nseq) {
|
||||
/* Get sequences for memory selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(mem_space, 0, &mem_iter, io_info->dxpl_cache->vec_size, nelmts, &mem_nseq, &mem_nelem, mem_off, mem_len) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_mem_seq = 0;
|
||||
} /* end if */
|
||||
|
||||
/* Perform I/O on memory and file sequences */
|
||||
if(io_buf->op_type == H5S_SELECT_READ) {
|
||||
if((tmp_file_len = (*io_info->ops.readvv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, io_buf->u.rbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
} /* end if */
|
||||
else {
|
||||
HDassert(io_buf->op_type == H5S_SELECT_WRITE);
|
||||
if((tmp_file_len = (*io_info->ops.writevv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, io_buf->u.wbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
} /* end else */
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
HDassert((tmp_file_len % elmt_size) == 0);
|
||||
nelmts -= (tmp_file_len / elmt_size);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
/* Release file selection iterator */
|
||||
if(file_iter_init)
|
||||
if(H5S_SELECT_ITER_RELEASE(&file_iter) < 0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
|
||||
|
||||
/* Release memory selection iterator */
|
||||
if(mem_iter_init)
|
||||
if(H5S_SELECT_ITER_RELEASE(&mem_iter) < 0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
|
||||
|
||||
/* Free vector arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if(file_len != NULL)
|
||||
H5FL_SEQ_FREE(size_t, file_len);
|
||||
if(file_off != NULL)
|
||||
H5FL_SEQ_FREE(hsize_t, file_off);
|
||||
if(mem_len != NULL)
|
||||
H5FL_SEQ_FREE(size_t, mem_len);
|
||||
if(mem_off != NULL)
|
||||
H5FL_SEQ_FREE(hsize_t, mem_off);
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D_select_io() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D_select_read
|
||||
@ -437,128 +639,21 @@ H5D_select_read(H5D_io_info_t *io_info,
|
||||
haddr_t addr, void *chunk/*in*/,
|
||||
void *buf/*out*/)
|
||||
{
|
||||
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
|
||||
hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
|
||||
H5S_sel_iter_t file_iter; /* File selection iteration info */
|
||||
hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
|
||||
hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
|
||||
hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */
|
||||
hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */
|
||||
hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */
|
||||
size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
|
||||
size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */
|
||||
size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */
|
||||
size_t *file_len=NULL; /* Pointer to sequence lengths in the file */
|
||||
size_t mem_nseq; /* Number of sequences generated in the file */
|
||||
size_t file_nseq; /* Number of sequences generated in memory */
|
||||
size_t mem_nelem; /* Number of elements used in memory sequences */
|
||||
size_t file_nelem; /* Number of elements used in file sequences */
|
||||
size_t curr_mem_seq; /* Current memory sequence to operate on */
|
||||
size_t curr_file_seq; /* Current file sequence to operate on */
|
||||
ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
H5D_select_buf_t io_buf; /* Selection I/O operation to perform */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5D_select_read, FAIL);
|
||||
FUNC_ENTER_NOAPI(H5D_select_read, FAIL)
|
||||
|
||||
/* Check args */
|
||||
assert(io_info);
|
||||
assert(io_info->dset);
|
||||
assert(io_info->dxpl_cache);
|
||||
assert(io_info->store);
|
||||
assert(buf);
|
||||
assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
|
||||
/* Construct proper I/O operation */
|
||||
io_buf.op_type = H5S_SELECT_READ;
|
||||
io_buf.u.rbuf = buf;
|
||||
|
||||
/* Initialize file iterator */
|
||||
if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
|
||||
file_iter_init=1; /* File selection iteration info has been initialized */
|
||||
|
||||
/* Initialize memory iterator */
|
||||
if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
|
||||
mem_iter_init=1; /* Memory selection iteration info has been initialized */
|
||||
|
||||
/* Allocate the vector I/O arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
|
||||
if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
|
||||
if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
|
||||
if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
|
||||
} /* end if */
|
||||
else {
|
||||
mem_len=_mem_len;
|
||||
mem_off=_mem_off;
|
||||
file_len=_file_len;
|
||||
file_off=_file_off;
|
||||
} /* end else */
|
||||
|
||||
/* Initialize sequence counts */
|
||||
curr_mem_seq=curr_file_seq=0;
|
||||
mem_nseq=file_nseq=0;
|
||||
|
||||
/* Loop, until all bytes are processed */
|
||||
while(nelmts>0) {
|
||||
/* Check if more file sequences are needed */
|
||||
if(curr_file_seq>=file_nseq) {
|
||||
/* Get sequences for file selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0)
|
||||
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_file_seq=0;
|
||||
} /* end if */
|
||||
|
||||
/* Check if more memory sequences are needed */
|
||||
if(curr_mem_seq>=mem_nseq) {
|
||||
/* Get sequences for memory selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0)
|
||||
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_mem_seq=0;
|
||||
} /* end if */
|
||||
|
||||
/* Read file sequences into current memory sequence */
|
||||
if ((tmp_file_len=(*io_info->ops.readvv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, buf))<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
assert((tmp_file_len%elmt_size)==0);
|
||||
nelmts-=(tmp_file_len/elmt_size);
|
||||
} /* end while */
|
||||
/* Call generic selection operation */
|
||||
if(H5D_select_io(io_info, nelmts, elmt_size, file_space, mem_space, addr, chunk, &io_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
|
||||
done:
|
||||
/* Release file selection iterator */
|
||||
if(file_iter_init) {
|
||||
if (H5S_SELECT_ITER_RELEASE(&file_iter)<0)
|
||||
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
|
||||
} /* end if */
|
||||
|
||||
/* Release memory selection iterator */
|
||||
if(mem_iter_init) {
|
||||
if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0)
|
||||
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
|
||||
} /* end if */
|
||||
|
||||
/* Free vector arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if(file_len!=NULL)
|
||||
H5FL_SEQ_FREE(size_t,file_len);
|
||||
if(file_off!=NULL)
|
||||
H5FL_SEQ_FREE(hsize_t,file_off);
|
||||
if(mem_len!=NULL)
|
||||
H5FL_SEQ_FREE(size_t,mem_len);
|
||||
if(mem_off!=NULL)
|
||||
H5FL_SEQ_FREE(hsize_t,mem_off);
|
||||
} /* end if */
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D_select_read() */
|
||||
|
||||
|
||||
@ -581,127 +676,20 @@ H5D_select_write(H5D_io_info_t *io_info,
|
||||
haddr_t addr, void *chunk/*in*/,
|
||||
const void *buf/*out*/)
|
||||
{
|
||||
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
|
||||
hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
|
||||
H5S_sel_iter_t file_iter; /* File selection iteration info */
|
||||
hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
|
||||
hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
|
||||
hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */
|
||||
hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */
|
||||
hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */
|
||||
size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
|
||||
size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */
|
||||
size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */
|
||||
size_t *file_len=NULL; /* Pointer to sequence lengths in the file */
|
||||
size_t mem_nseq; /* Number of sequences generated in the file */
|
||||
size_t file_nseq; /* Number of sequences generated in memory */
|
||||
size_t mem_nelem; /* Number of elements used in memory sequences */
|
||||
size_t file_nelem; /* Number of elements used in file sequences */
|
||||
size_t curr_mem_seq; /* Current memory sequence to operate on */
|
||||
size_t curr_file_seq; /* Current file sequence to operate on */
|
||||
ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
H5D_select_buf_t io_buf; /* Selection I/O operation to perform */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5D_select_write, FAIL);
|
||||
FUNC_ENTER_NOAPI(H5D_select_write, FAIL)
|
||||
|
||||
/* Check args */
|
||||
assert(io_info);
|
||||
assert(io_info->dset);
|
||||
assert(io_info->store);
|
||||
assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
|
||||
assert(buf);
|
||||
/* Construct proper I/O operation */
|
||||
io_buf.op_type = H5S_SELECT_WRITE;
|
||||
io_buf.u.wbuf = buf;
|
||||
|
||||
/* Allocate the vector I/O arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
|
||||
if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
|
||||
if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
|
||||
if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
|
||||
} /* end if */
|
||||
else {
|
||||
mem_len=_mem_len;
|
||||
mem_off=_mem_off;
|
||||
file_len=_file_len;
|
||||
file_off=_file_off;
|
||||
} /* end else */
|
||||
|
||||
/* Initialize file iterator */
|
||||
if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
|
||||
file_iter_init=1; /* File selection iteration info has been initialized */
|
||||
|
||||
/* Initialize memory iterator */
|
||||
if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
|
||||
mem_iter_init=1; /* Memory selection iteration info has been initialized */
|
||||
|
||||
/* Initialize sequence counts */
|
||||
curr_mem_seq=curr_file_seq=0;
|
||||
mem_nseq=file_nseq=0;
|
||||
|
||||
/* Loop, until all bytes are processed */
|
||||
while(nelmts>0) {
|
||||
/* Check if more file sequences are needed */
|
||||
if(curr_file_seq>=file_nseq) {
|
||||
/* Get sequences for file selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0)
|
||||
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_file_seq=0;
|
||||
} /* end if */
|
||||
|
||||
/* Check if more memory sequences are needed */
|
||||
if(curr_mem_seq>=mem_nseq) {
|
||||
/* Get sequences for memory selection */
|
||||
if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0)
|
||||
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
|
||||
|
||||
/* Start at the beginning of the sequences again */
|
||||
curr_mem_seq=0;
|
||||
} /* end if */
|
||||
|
||||
/* Write memory sequences into file sequences */
|
||||
if ((tmp_file_len=(*io_info->ops.writevv)(io_info,
|
||||
file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off,
|
||||
addr, chunk, buf))<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
assert((tmp_file_len%elmt_size)==0);
|
||||
nelmts-=(tmp_file_len/elmt_size);
|
||||
} /* end while */
|
||||
/* Call generic selection operation */
|
||||
if(H5D_select_io(io_info, nelmts, elmt_size, file_space, mem_space, addr, chunk, &io_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
|
||||
done:
|
||||
/* Release file selection iterator */
|
||||
if(file_iter_init) {
|
||||
if (H5S_SELECT_ITER_RELEASE(&file_iter)<0)
|
||||
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
|
||||
} /* end if */
|
||||
|
||||
/* Release memory selection iterator */
|
||||
if(mem_iter_init) {
|
||||
if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0)
|
||||
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
|
||||
} /* end if */
|
||||
|
||||
/* Free vector arrays */
|
||||
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
|
||||
if(file_len!=NULL)
|
||||
H5FL_SEQ_FREE(size_t,file_len);
|
||||
if(file_off!=NULL)
|
||||
H5FL_SEQ_FREE(hsize_t,file_off);
|
||||
if(mem_len!=NULL)
|
||||
H5FL_SEQ_FREE(size_t,mem_len);
|
||||
if(mem_off!=NULL)
|
||||
H5FL_SEQ_FREE(hsize_t,mem_off);
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D_select_write() */
|
||||
|
||||
|
61
src/H5Sall.c
61
src/H5Sall.c
@ -42,6 +42,7 @@ static hssize_t H5S_all_serial_size(const H5S_t *space);
|
||||
static herr_t H5S_all_serialize(const H5S_t *space, uint8_t *buf);
|
||||
static herr_t H5S_all_deserialize(H5S_t *space, const uint8_t *buf);
|
||||
static herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
|
||||
static herr_t H5S_all_offset(const H5S_t *space, hsize_t *off);
|
||||
static htri_t H5S_all_is_contiguous(const H5S_t *space);
|
||||
static htri_t H5S_all_is_single(const H5S_t *space);
|
||||
static htri_t H5S_all_is_regular(const H5S_t *space);
|
||||
@ -70,6 +71,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{
|
||||
H5S_all_serialize,
|
||||
H5S_all_deserialize,
|
||||
H5S_all_bounds,
|
||||
H5S_all_offset,
|
||||
H5S_all_is_contiguous,
|
||||
H5S_all_is_single,
|
||||
H5S_all_is_regular,
|
||||
@ -585,26 +587,61 @@ done:
|
||||
herr_t
|
||||
H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
|
||||
{
|
||||
int rank; /* Dataspace rank */
|
||||
int i; /* index variable */
|
||||
unsigned rank; /* Dataspace rank */
|
||||
unsigned i; /* index variable */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_all_bounds);
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_all_bounds)
|
||||
|
||||
assert(space);
|
||||
assert(start);
|
||||
assert(end);
|
||||
HDassert(space);
|
||||
HDassert(start);
|
||||
HDassert(end);
|
||||
|
||||
/* Get the dataspace extent rank */
|
||||
rank=space->extent.rank;
|
||||
rank = space->extent.rank;
|
||||
|
||||
/* Just copy over the complete extent */
|
||||
for(i=0; i<rank; i++) {
|
||||
start[i]=0;
|
||||
end[i]=space->extent.size[i]-1;
|
||||
for(i = 0; i < rank; i++) {
|
||||
start[i] = 0;
|
||||
end[i] = space->extent.size[i] - 1;
|
||||
} /* end for */
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||||
} /* H5Sget_all_bounds() */
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5S_all_bounds() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_all_offset
|
||||
PURPOSE
|
||||
Gets the linear offset of the first element for the selection.
|
||||
USAGE
|
||||
herr_t H5S_all_offset(space, offset)
|
||||
const H5S_t *space; IN: Dataspace pointer of selection to query
|
||||
hsize_t *offset; OUT: Linear offset of first element in selection
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Retrieves the linear offset (in "units" of elements) of the first element
|
||||
selected within the dataspace.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
Calling this function on a "none" selection returns fail.
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t
|
||||
H5S_all_offset(const H5S_t *space, hsize_t *offset)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_all_offset)
|
||||
|
||||
HDassert(space);
|
||||
HDassert(offset);
|
||||
|
||||
/* 'All' selections always start at offset 0 */
|
||||
*offset = 0;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5S_all_offset() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
119
src/H5Shyper.c
119
src/H5Shyper.c
@ -57,6 +57,7 @@ static hssize_t H5S_hyper_serial_size(const H5S_t *space);
|
||||
static herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t *buf);
|
||||
static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf);
|
||||
static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
|
||||
static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset);
|
||||
static htri_t H5S_hyper_is_contiguous(const H5S_t *space);
|
||||
static htri_t H5S_hyper_is_single(const H5S_t *space);
|
||||
static htri_t H5S_hyper_is_regular(const H5S_t *space);
|
||||
@ -90,6 +91,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
|
||||
H5S_hyper_serialize,
|
||||
H5S_hyper_deserialize,
|
||||
H5S_hyper_bounds,
|
||||
H5S_hyper_offset,
|
||||
H5S_hyper_is_contiguous,
|
||||
H5S_hyper_is_single,
|
||||
H5S_hyper_is_regular,
|
||||
@ -2705,6 +2707,114 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5S_hyper_bounds() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_hyper_offset
|
||||
PURPOSE
|
||||
Gets the linear offset of the first element for the selection.
|
||||
USAGE
|
||||
herr_t H5S_hyper_offset(space, offset)
|
||||
const H5S_t *space; IN: Dataspace pointer of selection to query
|
||||
hsize_t *offset; OUT: Linear offset of first element in selection
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Retrieves the linear offset (in "units" of elements) of the first element
|
||||
selected within the dataspace.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
Calling this function on a "none" selection returns fail.
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t
|
||||
H5S_hyper_offset(const H5S_t *space, hsize_t *offset)
|
||||
{
|
||||
const hssize_t *sel_offset; /* Pointer to the selection's offset */
|
||||
const hsize_t *dim_size; /* Pointer to a dataspace's extent */
|
||||
hsize_t accum; /* Accumulator for dimension sizes */
|
||||
int rank; /* Dataspace rank */
|
||||
int i; /* index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5S_hyper_offset, FAIL)
|
||||
|
||||
HDassert(space);
|
||||
HDassert(offset);
|
||||
|
||||
/* Start at linear offset 0 */
|
||||
*offset = 0;
|
||||
|
||||
/* Set up pointers to arrays of values */
|
||||
rank = space->extent.rank;
|
||||
sel_offset = space->select.offset;
|
||||
dim_size = space->extent.size;
|
||||
|
||||
/* Check for a "regular" hyperslab selection */
|
||||
if(space->select.sel_info.hslab->diminfo_valid) {
|
||||
const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */
|
||||
|
||||
/* Loop through starting coordinates, calculating the linear offset */
|
||||
accum = 1;
|
||||
for(i = (rank - 1); i >= 0; i--) {
|
||||
hssize_t hyp_offset = (hssize_t)diminfo[i].start + sel_offset[i]; /* Hyperslab's offset in this dimension */
|
||||
|
||||
/* Check for offset moving selection out of the dataspace */
|
||||
if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i])
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
|
||||
|
||||
/* Add the hyperslab's offset in this dimension to the total linear offset */
|
||||
*offset += hyp_offset * accum;
|
||||
|
||||
/* Increase the accumulator */
|
||||
accum *= dim_size[i];
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
else {
|
||||
const H5S_hyper_span_t *span; /* Hyperslab span node */
|
||||
hsize_t dim_accum[H5S_MAX_RANK]; /* Accumulators, for each dimension */
|
||||
|
||||
/* Calculate the accumulator for each dimension */
|
||||
accum = 1;
|
||||
for(i = (rank - 1); i >= 0; i--) {
|
||||
/* Set the accumulator for this dimension */
|
||||
dim_accum[i] = accum;
|
||||
|
||||
/* Increase the accumulator */
|
||||
accum *= dim_size[i];
|
||||
} /* end for */
|
||||
|
||||
/* Get information for the first span, in the slowest changing dimension */
|
||||
span = space->select.sel_info.hslab->span_lst->head;
|
||||
|
||||
/* Work down the spans, computing the linear offset */
|
||||
i = 0;
|
||||
while(span) {
|
||||
hssize_t hyp_offset = (hssize_t)span->low + sel_offset[i]; /* Hyperslab's offset in this dimension */
|
||||
|
||||
/* Check for offset moving selection out of the dataspace */
|
||||
if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i])
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
|
||||
|
||||
/* Add the hyperslab's offset in this dimension to the total linear offset */
|
||||
*offset += hyp_offset * dim_accum[i];
|
||||
|
||||
/* Advance to first span in "down" dimension */
|
||||
if(span->down) {
|
||||
HDassert(span->down->head);
|
||||
span = span->down->head;
|
||||
} /* end if */
|
||||
else
|
||||
span = NULL;
|
||||
i++;
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5S_hyper_offset() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
@ -2727,12 +2837,10 @@ done:
|
||||
htri_t
|
||||
H5S_hyper_is_contiguous(const H5S_t *space)
|
||||
{
|
||||
H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
|
||||
H5S_hyper_span_t *span; /* Hyperslab span node */
|
||||
unsigned u; /* index variable */
|
||||
unsigned small_contiguous, /* Flag for small contiguous block */
|
||||
large_contiguous; /* Flag for large contiguous block */
|
||||
htri_t ret_value=FALSE; /* return value */
|
||||
unsigned u; /* index variable */
|
||||
htri_t ret_value = FALSE; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_is_contiguous);
|
||||
|
||||
@ -2791,6 +2899,9 @@ H5S_hyper_is_contiguous(const H5S_t *space)
|
||||
ret_value=TRUE;
|
||||
} /* end if */
|
||||
else {
|
||||
H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
|
||||
H5S_hyper_span_t *span; /* Hyperslab span node */
|
||||
|
||||
/*
|
||||
* For a hyperslab to be contiguous, it must have only one block and
|
||||
* (either it's size must be the same as the dataspace extent's in all
|
||||
|
@ -43,6 +43,7 @@ static hssize_t H5S_none_serial_size(const H5S_t *space);
|
||||
static herr_t H5S_none_serialize(const H5S_t *space, uint8_t *buf);
|
||||
static herr_t H5S_none_deserialize(H5S_t *space, const uint8_t *buf);
|
||||
static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
|
||||
static herr_t H5S_none_offset(const H5S_t *space, hsize_t *off);
|
||||
static htri_t H5S_none_is_contiguous(const H5S_t *space);
|
||||
static htri_t H5S_none_is_single(const H5S_t *space);
|
||||
static htri_t H5S_none_is_regular(const H5S_t *space);
|
||||
@ -71,6 +72,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{
|
||||
H5S_none_serialize,
|
||||
H5S_none_deserialize,
|
||||
H5S_none_bounds,
|
||||
H5S_none_offset,
|
||||
H5S_none_is_contiguous,
|
||||
H5S_none_is_single,
|
||||
H5S_none_is_regular,
|
||||
@ -562,6 +564,38 @@ H5S_none_bounds(const H5S_t UNUSED *space, hsize_t UNUSED *start, hsize_t UNUSED
|
||||
FUNC_LEAVE_NOAPI(FAIL);
|
||||
} /* H5Sget_none_bounds() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_none_offset
|
||||
PURPOSE
|
||||
Gets the linear offset of the first element for the selection.
|
||||
USAGE
|
||||
herr_t H5S_none_offset(space, offset)
|
||||
const H5S_t *space; IN: Dataspace pointer of selection to query
|
||||
hsize_t *offset; OUT: Linear offset of first element in selection
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Retrieves the linear offset (in "units" of elements) of the first element
|
||||
selected within the dataspace.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
Calling this function on a "none" selection returns fail.
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t
|
||||
H5S_none_offset(const H5S_t *space, hsize_t *offset)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_none_offset)
|
||||
|
||||
HDassert(space);
|
||||
HDassert(offset);
|
||||
|
||||
FUNC_LEAVE_NOAPI(FAIL)
|
||||
} /* H5S_none_offset() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
@ -569,7 +603,7 @@ H5S_none_bounds(const H5S_t UNUSED *space, hsize_t UNUSED *start, hsize_t UNUSED
|
||||
PURPOSE
|
||||
Check if a "none" selection is contiguous within the dataspace extent.
|
||||
USAGE
|
||||
htri_t H5S_all_is_contiguous(space)
|
||||
htri_t H5S_none_is_contiguous(space)
|
||||
H5S_t *space; IN: Dataspace pointer to check
|
||||
RETURNS
|
||||
TRUE/FALSE/FAIL
|
||||
@ -767,7 +801,7 @@ done:
|
||||
PURPOSE
|
||||
Create a list of offsets & lengths for a selection
|
||||
USAGE
|
||||
herr_t H5S_all_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len)
|
||||
herr_t H5S_none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len)
|
||||
H5S_t *space; IN: Dataspace containing selection to use.
|
||||
unsigned flags; IN: Flags for extra information about operation
|
||||
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
|
||||
@ -816,4 +850,5 @@ H5S_none_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_
|
||||
*nelem=0;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||||
} /* end H5S_all_get_seq_list() */
|
||||
} /* end H5S_none_get_seq_list() */
|
||||
|
||||
|
@ -133,8 +133,10 @@ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space);
|
||||
typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t *buf);
|
||||
/* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
|
||||
typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, const uint8_t *buf);
|
||||
/* Method to determine to smallest n-D bounding box containing the current selection */
|
||||
/* Method to determine smallest n-D bounding box containing the current selection */
|
||||
typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end);
|
||||
/* Method to determine linear offset of initial element in selection within dataspace */
|
||||
typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset);
|
||||
/* Method to determine if current selection is contiguous */
|
||||
typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);
|
||||
/* Method to determine if current selection is a single block */
|
||||
@ -159,6 +161,7 @@ typedef struct {
|
||||
H5S_sel_serialize_func_t serialize; /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */
|
||||
H5S_sel_deserialize_func_t deserialize; /* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
|
||||
H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */
|
||||
H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */
|
||||
H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */
|
||||
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
|
||||
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
|
||||
|
110
src/H5Spoint.c
110
src/H5Spoint.c
@ -44,6 +44,7 @@ static hssize_t H5S_point_serial_size(const H5S_t *space);
|
||||
static herr_t H5S_point_serialize(const H5S_t *space, uint8_t *buf);
|
||||
static herr_t H5S_point_deserialize(H5S_t *space, const uint8_t *buf);
|
||||
static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
|
||||
static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off);
|
||||
static htri_t H5S_point_is_contiguous(const H5S_t *space);
|
||||
static htri_t H5S_point_is_single(const H5S_t *space);
|
||||
static htri_t H5S_point_is_regular(const H5S_t *space);
|
||||
@ -72,6 +73,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
|
||||
H5S_point_serialize,
|
||||
H5S_point_deserialize,
|
||||
H5S_point_bounds,
|
||||
H5S_point_offset,
|
||||
H5S_point_is_contiguous,
|
||||
H5S_point_is_single,
|
||||
H5S_point_is_regular,
|
||||
@ -1038,45 +1040,111 @@ static herr_t
|
||||
H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
|
||||
{
|
||||
H5S_pnt_node_t *node; /* Point node */
|
||||
int rank; /* Dataspace rank */
|
||||
int i; /* index variable */
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
unsigned rank; /* Dataspace rank */
|
||||
unsigned u; /* index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds);
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds)
|
||||
|
||||
assert(space);
|
||||
assert(start);
|
||||
assert(end);
|
||||
HDassert(space);
|
||||
HDassert(start);
|
||||
HDassert(end);
|
||||
|
||||
/* Get the dataspace extent rank */
|
||||
rank=space->extent.rank;
|
||||
rank = space->extent.rank;
|
||||
|
||||
/* Set the start and end arrays up */
|
||||
for(i=0; i<rank; i++) {
|
||||
start[i]=HSIZET_MAX;
|
||||
end[i]=0;
|
||||
for(u = 0; u < rank; u++) {
|
||||
start[u] = HSIZET_MAX;
|
||||
end[u] = 0;
|
||||
} /* end for */
|
||||
|
||||
/* Iterate through the node, checking the bounds on each element */
|
||||
node=space->select.sel_info.pnt_lst->head;
|
||||
while(node!=NULL) {
|
||||
for(i=0; i<rank; i++) {
|
||||
node = space->select.sel_info.pnt_lst->head;
|
||||
while(node != NULL) {
|
||||
for(u = 0; u < rank; u++) {
|
||||
/* Check for offset moving selection negative */
|
||||
if(((hssize_t)node->pnt[i]+space->select.offset[i])<0)
|
||||
if(((hssize_t)node->pnt[u] + space->select.offset[u]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
|
||||
|
||||
if(start[i]>(node->pnt[i]+space->select.offset[i]))
|
||||
start[i]=node->pnt[i]+space->select.offset[i];
|
||||
if(end[i]<(node->pnt[i]+space->select.offset[i]))
|
||||
end[i]=node->pnt[i]+space->select.offset[i];
|
||||
if(start[u] > (node->pnt[u] + space->select.offset[u]))
|
||||
start[u] = node->pnt[u] + space->select.offset[u];
|
||||
if(end[u] < (node->pnt[u] + space->select.offset[u]))
|
||||
end[u] = node->pnt[u] + space->select.offset[u];
|
||||
} /* end for */
|
||||
node=node->next;
|
||||
node = node->next;
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5S_point_bounds() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_point_offset
|
||||
PURPOSE
|
||||
Gets the linear offset of the first element for the selection.
|
||||
USAGE
|
||||
herr_t H5S_point_offset(space, offset)
|
||||
const H5S_t *space; IN: Dataspace pointer of selection to query
|
||||
hsize_t *offset; OUT: Linear offset of first element in selection
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Retrieves the linear offset (in "units" of elements) of the first element
|
||||
selected within the dataspace.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
Calling this function on a "none" selection returns fail.
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t
|
||||
H5S_point_offset(const H5S_t *space, hsize_t *offset)
|
||||
{
|
||||
const hsize_t *pnt; /* Pointer to a selected point's coordinates */
|
||||
const hssize_t *sel_offset; /* Pointer to the selection's offset */
|
||||
const hsize_t *dim_size; /* Pointer to a dataspace's extent */
|
||||
hsize_t accum; /* Accumulator for dimension sizes */
|
||||
int rank; /* Dataspace rank */
|
||||
int i; /* index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5S_point_offset, FAIL)
|
||||
|
||||
HDassert(space);
|
||||
HDassert(offset);
|
||||
|
||||
/* Start at linear offset 0 */
|
||||
*offset = 0;
|
||||
|
||||
/* Set up pointers to arrays of values */
|
||||
pnt = space->select.sel_info.pnt_lst->head->pnt;
|
||||
sel_offset = space->select.offset;
|
||||
dim_size = space->extent.size;
|
||||
|
||||
/* Loop through coordinates, calculating the linear offset */
|
||||
rank = space->extent.rank;
|
||||
accum = 1;
|
||||
for(i = (rank - 1); i >= 0; i--) {
|
||||
hssize_t pnt_offset = (hssize_t)pnt[i] + sel_offset[i]; /* Point's offset in this dimension */
|
||||
|
||||
/* Check for offset moving selection out of the dataspace */
|
||||
if(pnt_offset < 0 || (hsize_t)pnt_offset >= dim_size[i])
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
|
||||
|
||||
/* Add the point's offset in this dimension to the total linear offset */
|
||||
*offset += pnt_offset * accum;
|
||||
|
||||
/* Increase the accumulator */
|
||||
accum *= dim_size[i];
|
||||
} /* end for */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5S_point_offset() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
|
@ -152,6 +152,7 @@ typedef struct H5S_iostats_t {
|
||||
#define H5S_SELECT_SERIAL_SIZE(S) ((*(S)->select.type->serial_size)(S))
|
||||
#define H5S_SELECT_SERIALIZE(S,BUF) ((*(S)->select.type->serialize)(S,BUF))
|
||||
#define H5S_SELECT_BOUNDS(S,START,END) ((*(S)->select.type->bounds)(S,START,END))
|
||||
#define H5S_SELECT_OFFSET(S, OFFSET) ((*(S)->select.type->offset)(S, OFFSET))
|
||||
#define H5S_SELECT_IS_CONTIGUOUS(S) ((*(S)->select.type->is_contiguous)(S))
|
||||
#define H5S_SELECT_IS_SINGLE(S) ((*(S)->select.type->is_single)(S))
|
||||
#define H5S_SELECT_IS_REGULAR(S) ((*(S)->select.type->is_regular)(S))
|
||||
@ -175,6 +176,7 @@ typedef struct H5S_iostats_t {
|
||||
#define H5S_SELECT_SERIAL_SIZE(S) (H5S_select_serial_size(S))
|
||||
#define H5S_SELECT_SERIALIZE(S,BUF) (H5S_select_serialize(S,BUF))
|
||||
#define H5S_SELECT_BOUNDS(S,START,END) (H5S_get_select_bounds(S,START,END))
|
||||
#define H5S_SELECT_OFFSET(S, OFFSET) (H5S_get_select_offset(S, OFFSET))
|
||||
#define H5S_SELECT_IS_CONTIGUOUS(S) (H5S_select_is_contiguous(S))
|
||||
#define H5S_SELECT_IS_SINGLE(S) (H5S_select_is_single(S))
|
||||
#define H5S_SELECT_IS_REGULAR(S) (H5S_select_is_regular(S))
|
||||
@ -234,6 +236,7 @@ H5_DLL herr_t H5S_select_fill(const void *fill, size_t fill_size,
|
||||
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_get_select_offset(const H5S_t *space, hsize_t *offset);
|
||||
H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
|
||||
H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
|
||||
H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
|
||||
|
@ -576,6 +576,46 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5S_get_select_bounds() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_get_select_offset
|
||||
PURPOSE
|
||||
Gets the linear offset of the first element for the selection.
|
||||
USAGE
|
||||
herr_t H5S_get_select_offset(space, offset)
|
||||
const H5S_t *space; IN: Dataspace pointer of selection to query
|
||||
hsize_t *offset; OUT: Linear offset of first element in selection
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Retrieves the linear offset (in "units" of elements) of the first element
|
||||
selected within the dataspace.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
The offset calculation _does_ include the current offset of the
|
||||
selection within the dataspace extent.
|
||||
|
||||
Calling this function on a "none" selection returns fail.
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t
|
||||
H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
|
||||
{
|
||||
herr_t ret_value; /* return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_offset)
|
||||
|
||||
/* Check args */
|
||||
HDassert(space);
|
||||
HDassert(offset);
|
||||
|
||||
ret_value = (*space->select.type->offset)(space, offset);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5S_get_select_offset() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
|
@ -6059,7 +6059,8 @@ test_random_chunks(void)
|
||||
for(i = 0; i < NPOINTS; i++)
|
||||
if(rbuf[i] != wbuf[i]){
|
||||
printf(" Line %d: Incorrect value, wbuf[%u]=%d, rbuf[%u]=%d\n",__LINE__,(unsigned)i,wbuf[i],(unsigned)i,rbuf[i]);
|
||||
TEST_ERROR;
|
||||
printf(" coord[%u] = {%lu, %lu}\n", (unsigned)i, (unsigned long)coord[i][0], (unsigned long)coord[i][1]);
|
||||
TEST_ERROR;
|
||||
} /* end if */
|
||||
|
||||
/* Close resources */
|
||||
|
Loading…
Reference in New Issue
Block a user