mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-10-04 04:03:26 +03:00
Create a new, more streamlined method of generating I/O sequences when
there is only a single block defined by a hyperslab. This improves the
performance of Ger Van Diepen's (LOFAR team) benchmark by about 20%.
Tested on:
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, w/threadsafe, in production mode
Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode
Mac OS X/32 10.6.4 (amazon) in debug mode
Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode
2055 lines
76 KiB
C
2055 lines
76 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
* All rights reserved. *
|
|
* *
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
* is linked from the top-level documents page. It can also be found at *
|
|
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
|
* access to either file, you may request a copy from help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.ued>
|
|
* Friday, May 29, 1998
|
|
*
|
|
* Purpose: Dataspace selection functions.
|
|
*/
|
|
|
|
#define H5S_PACKAGE /*suppress error about including H5Spkg */
|
|
|
|
|
|
#include "H5private.h" /* Generic Functions */
|
|
#include "H5Dprivate.h" /* Datasets */
|
|
#include "H5Eprivate.h" /* Error handling */
|
|
#include "H5FLprivate.h" /* Free Lists */
|
|
#include "H5Iprivate.h" /* IDs */
|
|
#include "H5MMprivate.h" /* Memory management */
|
|
#include "H5Spkg.h" /* Dataspaces */
|
|
#include "H5Vprivate.h" /* Vector and array functions */
|
|
#include "H5WBprivate.h" /* Wrapped Buffers */
|
|
|
|
/* Local functions */
|
|
#ifdef LATER
|
|
static herr_t H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);
|
|
static htri_t H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter);
|
|
static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
|
|
#endif /* LATER */
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
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)
|
|
{
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_offset)
|
|
|
|
/* Check args */
|
|
HDassert(space);
|
|
HDassert(space->extent.rank);
|
|
HDassert(offset);
|
|
|
|
/* Copy the offset over */
|
|
HDmemcpy(space->select.offset, offset, sizeof(hssize_t)*space->extent.rank);
|
|
|
|
/* Indicate that the offset was changed */
|
|
space->select.offset_changed = TRUE;
|
|
|
|
FUNC_LEAVE_NOAPI(SUCCEED)
|
|
} /* H5S_select_offset() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_copy
|
|
PURPOSE
|
|
Copy a selection from one dataspace to another
|
|
USAGE
|
|
herr_t H5S_select_copy(dst, src)
|
|
H5S_t *dst; OUT: Pointer to the destination dataspace
|
|
H5S_t *src; IN: Pointer to the source dataspace
|
|
RETURNS
|
|
Non-negative on success/Negative on failure
|
|
DESCRIPTION
|
|
Copies all the selection information (include offset) from the source
|
|
dataspace to the destination dataspace.
|
|
|
|
If the SHARE_SELECTION flag is set, then the selection can be shared
|
|
between the source and destination dataspaces. (This should only occur in
|
|
situations where the destination dataspace will immediately change to a new
|
|
selection)
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_copy, FAIL)
|
|
|
|
/* Check args */
|
|
assert(dst);
|
|
assert(src);
|
|
|
|
/* Copy regular fields */
|
|
dst->select=src->select;
|
|
|
|
/* Perform correct type of copy based on the type of selection */
|
|
if((ret_value=(*src->select.type->copy)(dst,src,share_selection))<0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* 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
|
|
*
|
|
* Note: This routine participates in the "Inlining C function pointers"
|
|
* pattern, don't call it directly, use the appropriate macro
|
|
* defined in H5Sprivate.h.
|
|
*
|
|
* Modifications:
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5S_select_release(H5S_t *ds)
|
|
{
|
|
herr_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_release)
|
|
|
|
assert(ds);
|
|
|
|
/* Call the selection type's release function */
|
|
ret_value=(*ds->select.type->release)(ds);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_select_release() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5S_select_get_seq_list
|
|
*
|
|
* Purpose: Retrieves the next sequence of offset/length pairs for an
|
|
* iterator on a dataspace
|
|
*
|
|
* Return: Non-negative on success/Negative on failure
|
|
*
|
|
* Programmer: Quincey Koziol
|
|
* Tuesday, May 18, 2004
|
|
*
|
|
* Note: This routine participates in the "Inlining C function pointers"
|
|
* pattern, don't call it directly, use the appropriate macro
|
|
* defined in H5Sprivate.h.
|
|
*
|
|
* Modifications:
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
|
|
H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
|
|
size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len)
|
|
{
|
|
herr_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_get_seq_list)
|
|
|
|
HDassert(space);
|
|
|
|
/* Call the selection type's get_seq_list function */
|
|
ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_select_get_seq_list() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5S_select_serial_size
|
|
*
|
|
* Purpose: Determines the number of bytes required to store the current
|
|
* selection
|
|
*
|
|
* Return: Non-negative on success/Negative on failure
|
|
*
|
|
* Programmer: Quincey Koziol
|
|
* Tuesday, May 18, 2004
|
|
*
|
|
* Note: This routine participates in the "Inlining C function pointers"
|
|
* pattern, don't call it directly, use the appropriate macro
|
|
* defined in H5Sprivate.h.
|
|
*
|
|
* Modifications:
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hssize_t
|
|
H5S_select_serial_size(const H5S_t *space)
|
|
{
|
|
hssize_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serial_size)
|
|
|
|
assert(space);
|
|
|
|
/* Call the selection type's serial_size function */
|
|
ret_value=(*space->select.type->serial_size)(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_select_serial_size() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_serialize
|
|
PURPOSE
|
|
Serialize the selection for a dataspace into a buffer
|
|
USAGE
|
|
herr_t H5S_select_serialize(space, buf)
|
|
const H5S_t *space; IN: Dataspace with selection to serialize
|
|
uint8_t *buf; OUT: Buffer to put serialized selection
|
|
RETURNS
|
|
Non-negative on success/Negative on failure
|
|
DESCRIPTION
|
|
Calls the appropriate dataspace selection callback to serialize the
|
|
current selection into a buffer.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_serialize(const H5S_t *space, uint8_t *buf)
|
|
{
|
|
herr_t ret_value=SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serialize)
|
|
|
|
assert(space);
|
|
assert(buf);
|
|
|
|
/* Call the selection type's serialize function */
|
|
ret_value=(*space->select.type->serialize)(space,buf);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_select_serialize() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5Sget_select_npoints
|
|
PURPOSE
|
|
Get the number of elements in current selection
|
|
USAGE
|
|
hssize_t H5Sget_select_npoints(dsid)
|
|
hid_t dsid; IN: Dataspace ID of selection to query
|
|
RETURNS
|
|
Non-negative on success/Negative on failure
|
|
DESCRIPTION
|
|
Returns the number of elements in current selection for dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
hssize_t
|
|
H5Sget_select_npoints(hid_t spaceid)
|
|
{
|
|
H5S_t *space; /* Dataspace to modify selection of */
|
|
hssize_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_API(H5Sget_select_npoints, FAIL)
|
|
H5TRACE1("Hs", "i", spaceid);
|
|
|
|
/* Check args */
|
|
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
|
|
|
|
ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5Sget_select_npoints() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_get_select_npoints
|
|
PURPOSE
|
|
Get the number of elements in current selection
|
|
USAGE
|
|
hssize_t H5Sget_select_npoints(space)
|
|
H5S_t *space; IN: Dataspace of selection to query
|
|
RETURNS
|
|
The number of elements in selection on success, 0 on failure
|
|
DESCRIPTION
|
|
Returns the number of elements in current selection for dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
hssize_t
|
|
H5S_get_select_npoints(const H5S_t *space)
|
|
{
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_npoints)
|
|
|
|
/* Check args */
|
|
HDassert(space);
|
|
|
|
FUNC_LEAVE_NOAPI((hssize_t)space->select.num_elem)
|
|
} /* H5S_get_select_npoints() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5Sselect_valid
|
|
PURPOSE
|
|
Check whether the selection fits within the extent, with the current
|
|
offset defined.
|
|
USAGE
|
|
htri_t H5Sselect_void(dsid)
|
|
hid_t dsid; IN: Dataspace ID to query
|
|
RETURNS
|
|
TRUE if the selection fits within the extent, FALSE if it does not and
|
|
Negative on an error.
|
|
DESCRIPTION
|
|
Determines if the current selection at the current offet fits within the
|
|
extent for the dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
EXAMPLES
|
|
REVISION LOG
|
|
Christian Chilan 01/17/2007
|
|
Changed the error return value from 0 to FAIL.
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5Sselect_valid(hid_t spaceid)
|
|
{
|
|
H5S_t *space; /* Dataspace to modify selection of */
|
|
htri_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_API(H5Sselect_valid, FAIL)
|
|
H5TRACE1("t", "i", spaceid);
|
|
|
|
/* Check args */
|
|
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
|
|
|
|
ret_value = H5S_SELECT_VALID(space);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5Sselect_valid() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_valid
|
|
PURPOSE
|
|
Check whether the selection fits within the extent, with the current
|
|
offset defined.
|
|
USAGE
|
|
htri_t H5S_select_void(space)
|
|
H5S_t *space; IN: Dataspace to query
|
|
RETURNS
|
|
TRUE if the selection fits within the extent, FALSE if it does not and
|
|
Negative on an error.
|
|
DESCRIPTION
|
|
Determines if the current selection at the current offet fits within the
|
|
extent for the dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5S_select_valid(const H5S_t *space)
|
|
{
|
|
htri_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_valid)
|
|
|
|
assert(space);
|
|
|
|
ret_value = (*space->select.type->is_valid)(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_valid() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_deserialize
|
|
PURPOSE
|
|
Deserialize the current selection from a user-provided buffer into a real
|
|
selection in the dataspace.
|
|
USAGE
|
|
herr_t H5S_select_deserialize(space, buf)
|
|
H5S_t *space; IN/OUT: Dataspace pointer to place selection into
|
|
uint8 *buf; IN: Buffer to retrieve serialized selection from
|
|
RETURNS
|
|
Non-negative on success/Negative on failure
|
|
DESCRIPTION
|
|
Deserializes the current selection into a buffer. (Primarily for retrieving
|
|
from disk). This routine just hands off to the appropriate routine for each
|
|
type of selection. The format of the serialized information is shown in
|
|
the H5S_select_serialize() header.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
|
|
{
|
|
const uint8_t *tbuf; /* Temporary pointer to the selection type */
|
|
uint32_t sel_type; /* Pointer to the selection type */
|
|
herr_t ret_value=FAIL; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_deserialize, FAIL)
|
|
|
|
assert(space);
|
|
|
|
tbuf=buf;
|
|
UINT32DECODE(tbuf, sel_type);
|
|
switch(sel_type) {
|
|
case H5S_SEL_POINTS: /* Sequence of points selected */
|
|
ret_value=(*H5S_sel_point->deserialize)(space,buf);
|
|
break;
|
|
|
|
case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
|
|
ret_value=(*H5S_sel_hyper->deserialize)(space,buf);
|
|
break;
|
|
|
|
case H5S_SEL_ALL: /* Entire extent selected */
|
|
ret_value=(*H5S_sel_all->deserialize)(space,buf);
|
|
break;
|
|
|
|
case H5S_SEL_NONE: /* Nothing selected */
|
|
ret_value=(*H5S_sel_none->deserialize)(space,buf);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
if(ret_value<0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_deserialize() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5Sget_select_bounds
|
|
PURPOSE
|
|
Gets the bounding box containing the selection.
|
|
USAGE
|
|
herr_t H5S_get_select_bounds(space, start, end)
|
|
hid_t dsid; 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
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
|
|
{
|
|
H5S_t *space; /* Dataspace to modify selection of */
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_API(H5Sget_select_bounds, FAIL)
|
|
H5TRACE3("e", "i*h*h", spaceid, start, end);
|
|
|
|
/* Check args */
|
|
if(start == NULL || end == NULL)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
|
|
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
|
|
|
|
ret_value = H5S_SELECT_BOUNDS(space, start, end);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5Sget_select_bounds() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
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_NOFUNC(H5S_get_select_bounds)
|
|
|
|
/* Check args */
|
|
assert(space);
|
|
assert(start);
|
|
assert(end);
|
|
|
|
ret_value = (*space->select.type->bounds)(space,start,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
|
|
H5S_select_is_contiguous
|
|
PURPOSE
|
|
Determines if a selection is contiguous in the dataspace
|
|
USAGE
|
|
htri_t H5S_select_is_contiguous(space)
|
|
const H5S_t *space; IN: Dataspace of selection to query
|
|
RETURNS
|
|
Non-negative (TRUE/FALSE) on success, negative on failure
|
|
DESCRIPTION
|
|
Checks the selection to determine if the points to iterated over will be
|
|
contiguous in the particular dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5S_select_is_contiguous(const H5S_t *space)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_contiguous)
|
|
|
|
/* Check args */
|
|
assert(space);
|
|
|
|
ret_value = (*space->select.type->is_contiguous)(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_is_contiguous() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_is_single
|
|
PURPOSE
|
|
Determines if a selection is a single block in the dataspace
|
|
USAGE
|
|
htri_t H5S_select_is_single(space)
|
|
const H5S_t *space; IN: Dataspace of selection to query
|
|
RETURNS
|
|
Non-negative (TRUE/FALSE) on success, negative on failure
|
|
DESCRIPTION
|
|
Checks the selection to determine if it occupies a single block in the
|
|
particular dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5S_select_is_single(const H5S_t *space)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_single)
|
|
|
|
/* Check args */
|
|
assert(space);
|
|
|
|
ret_value = (*space->select.type->is_single)(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_is_single() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_is_regular
|
|
PURPOSE
|
|
Determines if a selection is "regular" in the dataspace
|
|
USAGE
|
|
htri_t H5S_select_is_regular(space)
|
|
const H5S_t *space; IN: Dataspace of selection to query
|
|
RETURNS
|
|
Non-negative (TRUE/FALSE) on success, negative on failure
|
|
DESCRIPTION
|
|
Checks the selection to determine if it is "regular" (i.e. a single
|
|
block or a strided pattern) in the particular dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5S_select_is_regular(const H5S_t *space)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_regular)
|
|
|
|
/* Check args */
|
|
assert(space);
|
|
|
|
ret_value = (*space->select.type->is_regular)(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_is_regular() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_adjust_u
|
|
PURPOSE
|
|
Adjust a selection by subtracting an offset
|
|
USAGE
|
|
herr_t H5S_select_adjust_u(space, offset)
|
|
H5S_t *space; IN/OUT: Pointer to dataspace to adjust
|
|
const hsize_t *offset; IN: Offset to subtract
|
|
RETURNS
|
|
Non-negative on success, negative on failure
|
|
DESCRIPTION
|
|
Moves a selection by subtracting an offset from it.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_adjust_u)
|
|
|
|
/* Check args */
|
|
HDassert(space);
|
|
|
|
ret_value = (*space->select.type->adjust_u)(space, offset);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_adjust_u() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_project_scalar
|
|
PURPOSE
|
|
Project a single element selection for a scalar dataspace
|
|
USAGE
|
|
herr_t H5S_select_project_scalar(space, offset)
|
|
const H5S_t *space; IN: Pointer to dataspace to project
|
|
hsize_t *offset; IN/OUT: Offset of projected point
|
|
RETURNS
|
|
Non-negative on success, negative on failure
|
|
DESCRIPTION
|
|
Projects a selection of a single element into a scalar dataspace, computing
|
|
the offset of the element in the original selection.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
|
|
{
|
|
herr_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_project_scalar)
|
|
|
|
/* Check args */
|
|
HDassert(space);
|
|
HDassert(offset);
|
|
|
|
ret_value = (*space->select.type->project_scalar)(space, offset);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_project_scalar() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_project_simple
|
|
PURPOSE
|
|
Project a selection onto/into a dataspace of different rank
|
|
USAGE
|
|
herr_t H5S_select_project_simple(space, new_space, offset)
|
|
const H5S_t *space; IN: Pointer to dataspace to project
|
|
H5S_t *new_space; IN/OUT: Pointer to dataspace projected onto
|
|
hsize_t *offset; IN/OUT: Offset of projected point
|
|
RETURNS
|
|
Non-negative on success, negative on failure
|
|
DESCRIPTION
|
|
Projects a selection onto/into a simple dataspace, computing
|
|
the offset of the first element in the original selection.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
|
|
{
|
|
herr_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_project_simple)
|
|
|
|
/* Check args */
|
|
HDassert(space);
|
|
HDassert(new_space);
|
|
HDassert(offset);
|
|
|
|
ret_value = (*space->select.type->project_simple)(space, new_space, offset);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_project_simple() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_init
|
|
PURPOSE
|
|
Initializes iteration information for a selection.
|
|
USAGE
|
|
herr_t H5S_select_iter_init(sel_iter, space, elmt_size)
|
|
H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize.
|
|
H5S_t *space; IN: Dataspace object containing selection to
|
|
iterate over
|
|
size_t elmt_size; IN: Size of elements in the selection
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
Initialize the selection iterator object to point to the first element
|
|
in the dataspace's selection.
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size)
|
|
{
|
|
herr_t ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_init)
|
|
|
|
/* Check args */
|
|
assert(sel_iter);
|
|
assert(space);
|
|
|
|
/* Initialize common information */
|
|
|
|
/* Save the dataspace's rank */
|
|
sel_iter->rank=space->extent.rank;
|
|
|
|
/* Point to the dataspace dimensions, if there are any */
|
|
if(sel_iter->rank > 0)
|
|
sel_iter->dims = space->extent.size;
|
|
else
|
|
sel_iter->dims = NULL;
|
|
|
|
/* Save the element size */
|
|
sel_iter->elmt_size=elmt_size;
|
|
|
|
/* Call initialization routine for selection type */
|
|
ret_value= (*space->select.type->iter_init)(sel_iter, space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_init() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_coords
|
|
PURPOSE
|
|
Get the coordinates of the current iterator position
|
|
USAGE
|
|
herr_t H5S_select_iter_coords(sel_iter,coords)
|
|
H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
|
|
hsize_t *coords; OUT: Array to place iterator coordinates in
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
The current location of the iterator within the selection is placed in
|
|
the COORDS array.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hsize_t *coords)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_coords)
|
|
|
|
/* Check args */
|
|
assert(sel_iter);
|
|
assert(coords);
|
|
|
|
/* Call iter_coords routine for selection type */
|
|
ret_value = (*sel_iter->type->iter_coords)(sel_iter,coords);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_coords() */
|
|
|
|
#ifdef LATER
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_block
|
|
PURPOSE
|
|
Get the block of the current iterator position
|
|
USAGE
|
|
herr_t H5S_select_iter_block(sel_iter,start,end)
|
|
const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
|
|
hsize_t *start; OUT: Array to place iterator start block coordinates
|
|
hsize_t *end; OUT: Array to place iterator end block coordinates
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
The current location of the iterator within the selection is placed in
|
|
the COORDS array.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
static herr_t
|
|
H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_block)
|
|
|
|
/* Check args */
|
|
assert(iter);
|
|
assert(start);
|
|
assert(end);
|
|
|
|
/* Call iter_block routine for selection type */
|
|
ret_value = (*iter->type->iter_block)(iter,start,end);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_block() */
|
|
#endif /* LATER */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_nelmts
|
|
PURPOSE
|
|
Get the number of elements left to iterate over in selection
|
|
USAGE
|
|
hssize_t H5S_select_iter_nelmts(sel_iter)
|
|
H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
|
|
RETURNS
|
|
The number of elements in selection on success, 0 on failure
|
|
DESCRIPTION
|
|
Returns the number of elements in current selection for dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
hsize_t
|
|
H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
|
|
{
|
|
hsize_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_nelmts)
|
|
|
|
/* Check args */
|
|
assert(sel_iter);
|
|
|
|
/* Call iter_nelmts routine for selection type */
|
|
ret_value = (*sel_iter->type->iter_nelmts)(sel_iter);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_nelmts() */
|
|
|
|
#ifdef LATER
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_has_next_block
|
|
PURPOSE
|
|
Check if there is another block available in the selection iterator
|
|
USAGE
|
|
htri_t H5S_select_iter_has_next_block(sel_iter)
|
|
const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
Check if there is another block available to advance to in the selection
|
|
iterator.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
static htri_t
|
|
H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_has_next_block)
|
|
|
|
/* Check args */
|
|
assert(iter);
|
|
|
|
/* Call iter_has_next_block routine for selection type */
|
|
ret_value = (*iter->type->iter_has_next_block)(iter);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_has_next_block() */
|
|
#endif /* LATER */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_next
|
|
PURPOSE
|
|
Advance selection iterator to next element
|
|
USAGE
|
|
herr_t H5S_select_iter_next(iter, nelem)
|
|
H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
|
|
size_t nelem; IN: Number of elements to advance by
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
Move the current element for the selection iterator to the NELEM'th next
|
|
element in the selection.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_next)
|
|
|
|
/* Check args */
|
|
assert(iter);
|
|
assert(nelem>0);
|
|
|
|
/* Call iter_next routine for selection type */
|
|
ret_value = (*iter->type->iter_next)(iter,nelem);
|
|
|
|
/* Decrement the number of elements left in selection */
|
|
iter->elmt_left-=nelem;
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_next() */
|
|
|
|
#ifdef LATER
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_next_block
|
|
PURPOSE
|
|
Advance selection iterator to next block
|
|
USAGE
|
|
herr_t H5S_select_iter_next_block(iter)
|
|
H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
|
|
RETURNS
|
|
Non-negative on success, negative on failure.
|
|
DESCRIPTION
|
|
Move the current element for the selection iterator to the next
|
|
block in the selection.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
Doesn't maintain the 'elmt_left' field of the selection iterator.
|
|
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
static herr_t
|
|
H5S_select_iter_next_block(H5S_sel_iter_t *iter)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_next_block)
|
|
|
|
/* Check args */
|
|
assert(iter);
|
|
|
|
/* Call iter_next_block routine for selection type */
|
|
ret_value = (*iter->type->iter_next_block)(iter);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_next_block() */
|
|
#endif /* LATER */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iter_release
|
|
PURPOSE
|
|
Release a selection iterator's resources.
|
|
USAGE
|
|
hssize_t H5S_select_iter_release(sel_iter)
|
|
H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
|
|
RETURNS
|
|
The number of elements in selection on success, 0 on failure
|
|
DESCRIPTION
|
|
Returns the number of elements in current selection for dataspace.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
|
|
{
|
|
herr_t ret_value; /* return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_release)
|
|
|
|
/* Check args */
|
|
assert(sel_iter);
|
|
|
|
/* Call selection type-specific release routine */
|
|
ret_value = (*sel_iter->type->iter_release)(sel_iter);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_iter_release() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_iterate
|
|
PURPOSE
|
|
Iterate over the selected elements in a memory buffer.
|
|
USAGE
|
|
herr_t H5S_select_iterate(buf, type_id, space, operator, operator_data)
|
|
void *buf; IN/OUT: Buffer containing elements to iterate over
|
|
hid_t type_id; IN: Datatype ID of BUF array.
|
|
H5S_t *space; IN: Dataspace object containing selection to iterate over
|
|
H5D_operator_t op; IN: Function pointer to the routine to be
|
|
called for each element in BUF iterated over.
|
|
void *operator_data; IN/OUT: Pointer to any user-defined data
|
|
associated with the operation.
|
|
RETURNS
|
|
Returns the return value of the last operator if it was non-zero, or zero
|
|
if all elements were processed. Otherwise returns a negative value.
|
|
DESCRIPTION
|
|
Iterates over the selected elements in a memory buffer, calling the user's
|
|
callback function for each element. The selection in the dataspace is
|
|
modified so that any elements already iterated over are removed from the
|
|
selection if the iteration is interrupted (by the H5D_operator_t function
|
|
returning non-zero) in the "middle" of the iteration and may be re-started
|
|
by the user where it left off.
|
|
|
|
NOTE: Until "subtracting" elements from a selection is implemented,
|
|
the selection is not modified.
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op,
|
|
void *operator_data)
|
|
{
|
|
H5T_t *dt; /* Datatype structure */
|
|
H5S_sel_iter_t iter; /* Selection iteration info */
|
|
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
|
|
uint8_t *loc; /* Current element location in buffer */
|
|
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */
|
|
hssize_t nelmts; /* Number of elements in selection */
|
|
hsize_t space_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
|
|
hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
|
|
hsize_t curr_off; /* Current offset within sequence */
|
|
hsize_t tmp_off; /* Temporary offset within sequence */
|
|
size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
|
|
size_t curr_len; /* Length of bytes left to process in sequence */
|
|
size_t nseq; /* Number of sequences generated */
|
|
size_t curr_seq; /* Current sequnce being worked on */
|
|
size_t nelem; /* Number of elements used in sequences */
|
|
size_t max_elem; /* Maximum number of elements allowed in sequences */
|
|
size_t elmt_size; /* Datatype size */
|
|
unsigned ndims; /* Number of dimensions in dataspace */
|
|
int i; /* Local Index variable */
|
|
herr_t user_ret=0; /* User's return value */
|
|
herr_t ret_value=SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_iterate, FAIL)
|
|
|
|
/* Check args */
|
|
HDassert(buf);
|
|
HDassert(H5I_DATATYPE == H5I_get_type(type_id));
|
|
HDassert(space);
|
|
HDassert(op);
|
|
|
|
/* Get the datatype size */
|
|
if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
|
|
if(0 == (elmt_size = H5T_get_size(dt)))
|
|
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
|
|
|
|
/* Initialize iterator */
|
|
if(H5S_select_iter_init(&iter, space, elmt_size) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
|
iter_init = TRUE; /* Selection iteration info has been initialized */
|
|
|
|
/* Get the number of elements in selection */
|
|
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
|
|
|
|
/* Get the rank of the dataspace */
|
|
ndims = space->extent.rank;
|
|
|
|
if(ndims > 0) {
|
|
/* Copy the size of the space */
|
|
HDassert(space->extent.size);
|
|
HDmemcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
|
|
} /* end if */
|
|
space_size[ndims] = elmt_size;
|
|
|
|
/* Compute the maximum number of bytes required */
|
|
H5_ASSIGN_OVERFLOW(max_elem, nelmts, hssize_t, size_t);
|
|
|
|
/* Loop, while elements left in selection */
|
|
while(max_elem > 0 && user_ret == 0) {
|
|
/* Get the sequences of bytes */
|
|
if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
|
|
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
|
|
|
|
/* Loop, while sequences left to process */
|
|
for(curr_seq=0; curr_seq<nseq && user_ret==0; curr_seq++) {
|
|
/* Get the current offset */
|
|
curr_off = off[curr_seq];
|
|
|
|
/* Get the number of bytes in sequence */
|
|
curr_len = len[curr_seq];
|
|
|
|
/* Loop, while bytes left in sequence */
|
|
while(curr_len > 0 && user_ret == 0) {
|
|
/* Compute the coordinate from the offset */
|
|
for(i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
|
|
coords[i] = tmp_off % space_size[i];
|
|
tmp_off /= space_size[i];
|
|
} /* end for */
|
|
|
|
/* Get the location within the user's buffer */
|
|
loc = (unsigned char *)buf + curr_off;
|
|
|
|
/* Call user's callback routine */
|
|
user_ret=(*op)(loc,type_id,ndims,coords,operator_data);
|
|
|
|
/* Increment offset in dataspace */
|
|
curr_off+=elmt_size;
|
|
|
|
/* Decrement number of bytes left in sequence */
|
|
curr_len-=elmt_size;
|
|
} /* end while */
|
|
} /* end for */
|
|
|
|
/* Decrement number of elements left to process */
|
|
max_elem-=nelem;
|
|
} /* end while */
|
|
|
|
/* Set return value */
|
|
ret_value=user_ret;
|
|
|
|
done:
|
|
/* Release selection iterator */
|
|
if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
|
|
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_select_iterate() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5Sget_select_type
|
|
PURPOSE
|
|
Retrieve the type of selection in a dataspace
|
|
USAGE
|
|
H5S_sel_type H5Sget_select_type(space_id)
|
|
hid_t space_id; IN: Dataspace object to query
|
|
RETURNS
|
|
Non-negative on success/Negative on failure. Return value is from the
|
|
set of values in the H5S_sel_type enumerated type.
|
|
DESCRIPTION
|
|
This function retrieves the type of selection currently defined for
|
|
a dataspace.
|
|
--------------------------------------------------------------------------*/
|
|
H5S_sel_type
|
|
H5Sget_select_type(hid_t space_id)
|
|
{
|
|
H5S_t *space; /* dataspace to modify */
|
|
H5S_sel_type ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5Sget_select_type, H5S_SEL_ERROR)
|
|
H5TRACE1("St", "i", space_id);
|
|
|
|
/* Check args */
|
|
if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
|
|
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace")
|
|
|
|
/* Set return value */
|
|
ret_value = H5S_GET_SELECT_TYPE(space);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5Sget_select_type() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_get_select_type
|
|
PURPOSE
|
|
Retrieve the type of selection in a dataspace
|
|
USAGE
|
|
H5S_sel_type H5Sget_select_type(space)
|
|
const H5S_t *space; IN: Dataspace object to query
|
|
RETURNS
|
|
Non-negative on success/Negative on failure. Return value is from the
|
|
set of values in the H5S_sel_type enumerated type.
|
|
DESCRIPTION
|
|
This function retrieves the type of selection currently defined for
|
|
a dataspace.
|
|
COMMENTS
|
|
This routine participates in the "Inlining C function pointers"
|
|
pattern, don't call it directly, use the appropriate macro
|
|
defined in H5Sprivate.h.
|
|
--------------------------------------------------------------------------*/
|
|
H5S_sel_type
|
|
H5S_get_select_type(const H5S_t *space)
|
|
{
|
|
H5S_sel_type ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_type)
|
|
|
|
/* Check args */
|
|
assert(space);
|
|
|
|
/* Set return value */
|
|
ret_value=H5S_GET_SELECT_TYPE(space);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5S_get_select_type() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_shape_same
|
|
PURPOSE
|
|
Check if two selections are the same shape
|
|
USAGE
|
|
htri_t H5S_select_shape_same(space1, space2)
|
|
const H5S_t *space1; IN: 1st Dataspace pointer to compare
|
|
const H5S_t *space2; IN: 2nd Dataspace pointer to compare
|
|
RETURNS
|
|
TRUE/FALSE/FAIL
|
|
DESCRIPTION
|
|
Checks to see if the current selection in the dataspaces are the same
|
|
dimensionality and shape.
|
|
This is primarily used for reading the entire selection in one swoop.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
Assumes that there is only a single "block" for hyperslab selections.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
Modified function to view identical shapes with different dimensions
|
|
as being the same under some circumstances.
|
|
--------------------------------------------------------------------------*/
|
|
htri_t
|
|
H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
|
|
{
|
|
H5S_sel_iter_t iter_a; /* Selection a iteration info */
|
|
H5S_sel_iter_t iter_b; /* Selection b iteration info */
|
|
hbool_t iter_a_init = 0; /* Selection a iteration info has been initialized */
|
|
hbool_t iter_b_init = 0; /* Selection b iteration info has been initialized */
|
|
htri_t ret_value = TRUE; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_shape_same, FAIL)
|
|
|
|
/* Check args */
|
|
HDassert(space1);
|
|
HDassert(space2);
|
|
|
|
/* Special case for one or both dataspaces being scalar */
|
|
if(space1->extent.rank == 0 || space2->extent.rank == 0) {
|
|
/* Check for different number of elements selected */
|
|
if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
|
|
HGOTO_DONE(FALSE)
|
|
} /* end if */
|
|
else {
|
|
const H5S_t *space_a; /* Dataspace with larger rank */
|
|
const H5S_t *space_b; /* Dataspace with smaller rank */
|
|
unsigned space_a_rank; /* Number of dimensions of dataspace A */
|
|
unsigned space_b_rank; /* Number of dimensions of dataspace B */
|
|
|
|
/* need to be able to handle spaces of different rank:
|
|
*
|
|
* To simplify logic, let space_a point to the element of the set
|
|
* {space1, space2} with the largest rank or space1 if the ranks
|
|
* are identical.
|
|
*
|
|
* Similarly, let space_b point to the element of {space1, space2}
|
|
* with the smallest rank, or space2 if they are identical.
|
|
*
|
|
* Let: space_a_rank be the rank of space_a,
|
|
* space_b_rank be the rank of space_b,
|
|
* delta_rank = space_a_rank - space_b_rank.
|
|
*
|
|
* Set all this up below.
|
|
*/
|
|
if(space1->extent.rank >= space2->extent.rank) {
|
|
space_a = space1;
|
|
space_a_rank = space_a->extent.rank;
|
|
|
|
space_b = space2;
|
|
space_b_rank = space_b->extent.rank;
|
|
} /* end if */
|
|
else {
|
|
space_a = space2;
|
|
space_a_rank = space_a->extent.rank;
|
|
|
|
space_b = space1;
|
|
space_b_rank = space_b->extent.rank;
|
|
} /* end else */
|
|
HDassert(space_a_rank >= space_b_rank);
|
|
HDassert(space_b_rank > 0);
|
|
|
|
/* Check for different number of elements selected */
|
|
if(H5S_GET_SELECT_NPOINTS(space_a) != H5S_GET_SELECT_NPOINTS(space_b))
|
|
HGOTO_DONE(FALSE)
|
|
|
|
/* Check for "easy" cases before getting into generalized block iteration code */
|
|
if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_ALL) && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_ALL)) {
|
|
hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
|
|
hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
|
|
int space_a_dim; /* Current dimension in dataspace A */
|
|
int space_b_dim; /* Current dimension in dataspace B */
|
|
|
|
if(H5S_get_simple_extent_dims(space_a, dims1, NULL) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
|
|
if(H5S_get_simple_extent_dims(space_b, dims2, NULL) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
|
|
|
|
space_a_dim = (int)space_a_rank - 1;
|
|
space_b_dim = (int)space_b_rank - 1;
|
|
|
|
/* recall that space_a_rank >= space_b_rank.
|
|
*
|
|
* In the following while loop, we test to see if space_a and space_b
|
|
* have identical size in all dimensions they have in common.
|
|
*/
|
|
while(space_b_dim >= 0) {
|
|
if(dims1[space_a_dim] != dims2[space_b_dim])
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
space_b_dim--;
|
|
} /* end while */
|
|
|
|
/* Since we are selecting the entire spaces, we must also verify that space_a
|
|
* has size 1 in all dimensions that it does not share with space_b.
|
|
*/
|
|
while(space_a_dim >= 0) {
|
|
if(dims1[space_a_dim] != 1)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
} /* end while */
|
|
} /* end if */
|
|
else if((H5S_GET_SELECT_TYPE(space1) == H5S_SEL_NONE) || (H5S_GET_SELECT_TYPE(space2) == H5S_SEL_NONE)) {
|
|
HGOTO_DONE(TRUE)
|
|
} /* end if */
|
|
else if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_HYPERSLABS && space_a->select.sel_info.hslab->diminfo_valid)
|
|
&& (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_HYPERSLABS && space_b->select.sel_info.hslab->diminfo_valid)) {
|
|
int space_a_dim; /* Current dimension in dataspace A */
|
|
int space_b_dim; /* Current dimension in dataspace B */
|
|
|
|
space_a_dim = (int)space_a_rank - 1;
|
|
space_b_dim = (int)space_b_rank - 1;
|
|
|
|
/* check that the shapes are the same in the common dimensions, and that
|
|
* block == 1 in all dimensions that appear only in space_a.
|
|
*/
|
|
while(space_b_dim >= 0) {
|
|
if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].stride !=
|
|
space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].stride)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].count !=
|
|
space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].count)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block !=
|
|
space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].block)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
space_b_dim--;
|
|
} /* end while */
|
|
|
|
while(space_a_dim >= 0) {
|
|
if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != 1)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
} /* end while */
|
|
} /* end if */
|
|
/* Iterate through all the blocks in the selection */
|
|
else {
|
|
hsize_t start_a[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace a */
|
|
hsize_t start_b[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace b */
|
|
hsize_t end_a[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace a */
|
|
hsize_t end_b[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace b */
|
|
hsize_t off_a[H5O_LAYOUT_NDIMS]; /* Offset of selection a blocks */
|
|
hsize_t off_b[H5O_LAYOUT_NDIMS]; /* Offset of selection b blocks */
|
|
hbool_t first_block = TRUE; /* Flag to indicate the first block */
|
|
|
|
/* Initialize iterator for each dataspace selection
|
|
* Use '0' for element size instead of actual element size to indicate
|
|
* that the selection iterator shouldn't be "flattened", since we
|
|
* aren't actually going to be doing I/O with the iterators.
|
|
*/
|
|
if(H5S_select_iter_init(&iter_a, space_a, (size_t)0) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a")
|
|
iter_a_init = 1;
|
|
if(H5S_select_iter_init(&iter_b, space_b, (size_t)0) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b")
|
|
iter_b_init = 1;
|
|
|
|
/* Iterate over all the blocks in each selection */
|
|
while(1) {
|
|
int space_a_dim; /* Current dimension in dataspace A */
|
|
int space_b_dim; /* Current dimension in dataspace B */
|
|
htri_t status_a, status_b; /* Status from next block checks */
|
|
|
|
/* Get the current block for each selection iterator */
|
|
if(H5S_SELECT_ITER_BLOCK(&iter_a, start_a, end_a) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block a")
|
|
if(H5S_SELECT_ITER_BLOCK(&iter_b, start_b, end_b) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block b")
|
|
|
|
space_a_dim = (int)space_a_rank - 1;
|
|
space_b_dim = (int)space_b_rank - 1;
|
|
|
|
/* The first block only compares the sizes and sets the
|
|
* relative offsets for later blocks
|
|
*/
|
|
if(first_block) {
|
|
/* If the block sizes in the common dimensions from
|
|
* each selection don't match, get out
|
|
*/
|
|
while(space_b_dim >= 0) {
|
|
if((end_a[space_a_dim] - start_a[space_a_dim]) !=
|
|
(end_b[space_b_dim] - start_b[space_b_dim]))
|
|
HGOTO_DONE(FALSE)
|
|
|
|
/* Set the relative locations of the selections */
|
|
off_a[space_a_dim] = start_a[space_a_dim];
|
|
off_b[space_b_dim] = start_b[space_b_dim];
|
|
|
|
space_a_dim--;
|
|
space_b_dim--;
|
|
} /* end while */
|
|
|
|
/* similarly, if the block size in any dimension that appears only
|
|
* in space_a is not equal to 1, get out.
|
|
*/
|
|
while(space_a_dim >= 0) {
|
|
if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
/* Set the relative locations of the selections */
|
|
off_a[space_a_dim] = start_a[space_a_dim];
|
|
|
|
space_a_dim--;
|
|
} /* end while */
|
|
|
|
/* Reset "first block" flag */
|
|
first_block = FALSE;
|
|
} /* end if */
|
|
/* Check over the blocks for each selection */
|
|
else {
|
|
/* for dimensions that space_a and space_b have in common: */
|
|
while(space_b_dim >= 0) {
|
|
/* Check if the blocks are in the same relative location */
|
|
if((start_a[space_a_dim] - off_a[space_a_dim]) !=
|
|
(start_b[space_b_dim] - off_b[space_b_dim]))
|
|
HGOTO_DONE(FALSE)
|
|
|
|
/* If the block sizes from each selection doesn't match, get out */
|
|
if((end_a[space_a_dim] - start_a[space_a_dim]) !=
|
|
(end_b[space_b_dim] - start_b[space_b_dim]))
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
space_b_dim--;
|
|
} /* end while */
|
|
|
|
/* For dimensions that appear only in space_a: */
|
|
while(space_a_dim >= 0) {
|
|
/* If the block size isn't 1, get out */
|
|
if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
|
|
HGOTO_DONE(FALSE)
|
|
|
|
space_a_dim--;
|
|
} /* end while */
|
|
} /* end else */
|
|
|
|
/* Check if we are able to advance to the next selection block */
|
|
if((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_a)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block a")
|
|
|
|
if((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_b)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b")
|
|
|
|
/* Did we run out of blocks at the same time? */
|
|
if((status_a == FALSE) && (status_b == FALSE))
|
|
break;
|
|
else if(status_a != status_b)
|
|
HGOTO_DONE(FALSE)
|
|
else {
|
|
/* Advance to next block in selection iterators */
|
|
if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_a) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block a")
|
|
|
|
if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_b) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block b")
|
|
} /* end else */
|
|
} /* end while */
|
|
} /* end else */
|
|
} /* end else */
|
|
|
|
done:
|
|
if(iter_a_init)
|
|
if(H5S_SELECT_ITER_RELEASE(&iter_a) < 0)
|
|
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a")
|
|
if(iter_b_init)
|
|
if(H5S_SELECT_ITER_RELEASE(&iter_b) < 0)
|
|
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b")
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_shape_same() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_construct_projection
|
|
|
|
PURPOSE
|
|
Given a dataspace a of rank n with some selection, construct a new
|
|
dataspace b of rank m (m != n), with the selection in a being
|
|
topologically identical to that in b (as verified by
|
|
H5S_select_shape_same().
|
|
|
|
This function exists, as some I/O code chokes of topologically
|
|
identical selections with different ranks. At least to begin
|
|
with, we will deal with the issue by constructing projections
|
|
of the memory dataspace with ranks equaling those of the file
|
|
dataspace.
|
|
|
|
Note that if m > n, it is possible that the starting point in the
|
|
buffer associated with the memory dataspace will have to be
|
|
adjusted to match the projected dataspace. If the buf parameter
|
|
is not NULL, the function must return an adjusted buffer base
|
|
address in *adj_buf_ptr.
|
|
|
|
USAGE
|
|
htri_t H5S_select_construct_projection(base_space,
|
|
new_space_ptr,
|
|
new_space_rank,
|
|
buf,
|
|
adj_buf_ptr)
|
|
const H5S_t *base_space; IN: Ptr to Dataspace to project
|
|
H5S_t ** new_space_ptr; OUT: Ptr to location in which to return
|
|
the address of the projected space
|
|
int new_space_rank; IN: Rank of the projected space.
|
|
const void * buf; IN: Base address of the buffer
|
|
associated with the base space.
|
|
May be NULL.
|
|
void ** adj_buf_ptr; OUT: If buf != NULL, store the base
|
|
address of the section of buf
|
|
that is described by *new_space_ptr
|
|
in *adj_buf_ptr.
|
|
|
|
RETURNS
|
|
Non-negative on success/Negative on failure.
|
|
|
|
DESCRIPTION
|
|
Construct a new dataspace and associated selection which is a
|
|
projection of the supplied dataspace and associated selection into
|
|
the specified rank. Return it in *new_space_ptr.
|
|
|
|
If buf is supplied, computes the base address of the projected
|
|
selection in buf, and stores the base address in *adj_buf_ptr.
|
|
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
The selection in the supplied base_space has thickness 1 in all
|
|
dimensions greater than new_space_rank. Note that here we count
|
|
dimensions from the fastest changing coordinate to the slowest
|
|
changing changing coordinate.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
|
|
unsigned new_space_rank, const void *buf, void const **adj_buf_ptr, hsize_t element_size)
|
|
{
|
|
H5S_t * new_space = NULL; /* New dataspace constructed */
|
|
hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */
|
|
hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */
|
|
int sbase_space_rank; /* Signed # of dimensions of base dataspace */
|
|
unsigned base_space_rank; /* # of dimensions of base dataspace */
|
|
hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_construct_projection, FAIL)
|
|
|
|
/* Sanity checks */
|
|
HDassert(base_space != NULL);
|
|
HDassert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) || (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE));
|
|
HDassert(new_space_ptr != NULL);
|
|
HDassert((new_space_rank != 0) || (H5S_GET_SELECT_NPOINTS(base_space) <= 1));
|
|
HDassert(new_space_rank <= H5S_MAX_RANK);
|
|
HDassert((buf == NULL) || (adj_buf_ptr != NULL));
|
|
HDassert(element_size > 0 );
|
|
|
|
/* Get the extent info for the base dataspace */
|
|
if((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality of base space")
|
|
base_space_rank = (unsigned)sbase_space_rank;
|
|
HDassert(base_space_rank != new_space_rank);
|
|
|
|
/* Check if projected space is scalar */
|
|
if(new_space_rank == 0) {
|
|
hssize_t npoints; /* Number of points selected */
|
|
|
|
/* Retreve the number of elements selected */
|
|
if((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected")
|
|
HDassert(npoints <= 1);
|
|
|
|
/* Create new scalar dataspace */
|
|
if(NULL == (new_space = H5S_create(H5S_SCALAR)))
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace")
|
|
|
|
/* No need to register the dataspace(i.e. get an ID) as
|
|
* we will just be discarding it shortly.
|
|
*/
|
|
|
|
/* Selection for the new space will be either all or
|
|
* none, depending on whether the base space has 0 or
|
|
* 1 elements selected.
|
|
*
|
|
* Observe that the base space can't have more than
|
|
* one selected element, since its selection has the
|
|
* same shape as the file dataspace, and that data
|
|
* space is scalar.
|
|
*/
|
|
if(1 == npoints) {
|
|
/* Assuming that the selection in the base dataspace is not
|
|
* empty, we must compute the offset of the selected item in
|
|
* the buffer associated with the base dataspace.
|
|
*
|
|
* Since the new space rank is zero, we know that the
|
|
* the base space must have rank at least 1 -- and
|
|
* hence it is a simple dataspace. However, the
|
|
* selection, may be either point, hyperspace, or all.
|
|
*
|
|
*/
|
|
if(H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection")
|
|
} /* end if */
|
|
else {
|
|
HDassert(0 == npoints);
|
|
|
|
if(H5S_select_none(new_space) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
|
|
} /* end else */
|
|
} /* end if */
|
|
else { /* projected space must be simple */
|
|
hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */
|
|
hsize_t new_space_maxdims[H5S_MAX_RANK];/* Maximum dimensions for new dataspace */
|
|
unsigned rank_diff; /* Difference in ranks */
|
|
|
|
/* Set up the dimensions of the new, projected dataspace.
|
|
*
|
|
* How we do this depends on whether we are projecting up into
|
|
* increased dimensions, or down into a reduced number of
|
|
* dimensions.
|
|
*
|
|
* If we are projecting up (the first half of the following
|
|
* if statement), we copy the dimensions of the base data
|
|
* space into the fastest changing dimensions of the new
|
|
* projected dataspace, and set the remaining dimensions to
|
|
* one.
|
|
*
|
|
* If we are projecting down (the second half of the following
|
|
* if statement), we just copy the dimensions with the most
|
|
* quickly changing dimensions into the dims for the projected
|
|
* data set.
|
|
*
|
|
* This works, because H5S_select_shape_same() will return
|
|
* true on selections of different rank iff:
|
|
*
|
|
* 1) the selection in the lower rank dataspace matches that
|
|
* in the dimensions with the fastest changing indicies in
|
|
* the larger rank dataspace, and
|
|
*
|
|
* 2) the selection has thickness 1 in all ranks that appear
|
|
* only in the higher rank dataspace (i.e. those with
|
|
* more slowly changing indicies).
|
|
*/
|
|
if(new_space_rank > base_space_rank) {
|
|
hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
|
|
|
|
/* we must copy the dimensions of the base space into
|
|
* the fastest changing dimensions of the new space,
|
|
* and set the remaining dimensions to 1
|
|
*/
|
|
rank_diff = new_space_rank - base_space_rank;
|
|
H5V_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
|
|
H5V_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
|
|
HDmemcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank);
|
|
HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank);
|
|
} /* end if */
|
|
else { /* new_space_rank < base_space_rank */
|
|
/* we must copy the fastest changing dimension of the
|
|
* base space into the dimensions of the new space.
|
|
*/
|
|
rank_diff = base_space_rank - new_space_rank;
|
|
HDmemcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank);
|
|
HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank);
|
|
} /* end else */
|
|
|
|
/* now have the new space rank and dimensions set up --
|
|
* so we can create the new simple dataspace.
|
|
*/
|
|
if(NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims)))
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
|
|
|
|
/* No need to register the dataspace(i.e. get an ID) as
|
|
* we will just be discarding it shortly.
|
|
*/
|
|
|
|
/* If we get this far, we have successfully created the projected
|
|
* dataspace. We must now project the selection in the base
|
|
* dataspace into the projected dataspace.
|
|
*/
|
|
if(H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection")
|
|
|
|
/* If we get this far, we have created the new dataspace, and projected
|
|
* the selection in the base dataspace into the new dataspace.
|
|
*
|
|
* If the base dataspace is simple, check to see if the
|
|
* offset_changed flag on the base selection has been set -- if so,
|
|
* project the offset into the new dataspace and set the
|
|
* offset_changed flag.
|
|
*/
|
|
if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) {
|
|
if(new_space_rank > base_space_rank) {
|
|
HDmemset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff);
|
|
HDmemcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank);
|
|
} /* end if */
|
|
else
|
|
HDmemcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank);
|
|
|
|
/* Propagate the offset changed flag into the new dataspace. */
|
|
new_space->select.offset_changed = TRUE;
|
|
} /* end if */
|
|
} /* end else */
|
|
|
|
/* If we have done the projection correctly, the following assertion
|
|
* should hold.
|
|
*/
|
|
HDassert(TRUE == H5S_select_shape_same(base_space, new_space));
|
|
|
|
/* load the address of the new space into *new_space_ptr */
|
|
*new_space_ptr = new_space;
|
|
|
|
/* now adjust the buffer if required */
|
|
if(buf != NULL) {
|
|
if(new_space_rank < base_space_rank) {
|
|
/* a bit of pointer magic here:
|
|
*
|
|
* Since we can't do pointer arithmetic on void pointers, we first
|
|
* cast buf to a pointer to byte -- i.e. uint8_t.
|
|
*
|
|
* We then multiply the projected space element offset we
|
|
* calculated earlier by the supplied element size, add this
|
|
* value to the type cast buf pointer, cast the result back
|
|
* to a pointer to void, and assign the result to *adj_buf_ptr.
|
|
*/
|
|
*adj_buf_ptr = (const void *)(((const uint8_t *)buf) +
|
|
((size_t)(projected_space_element_offset * element_size)));
|
|
} /* end if */
|
|
else
|
|
/* No adjustment necessary */
|
|
*adj_buf_ptr = buf;
|
|
} /* end if */
|
|
|
|
done:
|
|
/* Cleanup on error */
|
|
if(ret_value < 0) {
|
|
if(new_space && H5S_close(new_space) < 0)
|
|
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
|
|
} /* end if */
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_construct_projection() */
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
NAME
|
|
H5S_select_fill
|
|
PURPOSE
|
|
Fill a selection in memory with a value
|
|
USAGE
|
|
herr_t H5S_select_fill(fill,fill_size,space,buf)
|
|
const void *fill; IN: Pointer to fill value to use
|
|
size_t fill_size; IN: Size of elements in memory buffer & size of
|
|
fill value
|
|
H5S_t *space; IN: Dataspace describing memory buffer &
|
|
containing selection to use.
|
|
void *buf; IN/OUT: Memory buffer to fill selection in
|
|
RETURNS
|
|
Non-negative on success/Negative on failure.
|
|
DESCRIPTION
|
|
Use the selection in the dataspace to fill elements in a memory buffer.
|
|
GLOBAL VARIABLES
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
The memory buffer elements are assumed to have the same datatype as the
|
|
fill value being placed into them.
|
|
EXAMPLES
|
|
REVISION LOG
|
|
--------------------------------------------------------------------------*/
|
|
herr_t
|
|
H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
|
|
{
|
|
H5S_sel_iter_t iter; /* Selection iteration info */
|
|
hbool_t iter_init = 0; /* Selection iteration info has been initialized */
|
|
hssize_t nelmts; /* Number of elements in selection */
|
|
size_t max_elem; /* Total number of elements in selection */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_NOAPI(H5S_select_fill, FAIL)
|
|
|
|
/* Check args */
|
|
HDassert(fill);
|
|
HDassert(fill_size > 0);
|
|
HDassert(space);
|
|
HDassert(_buf);
|
|
|
|
/* Initialize iterator */
|
|
if(H5S_select_iter_init(&iter, space, fill_size) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
|
iter_init = 1; /* Selection iteration info has been initialized */
|
|
|
|
/* Get the number of elements in selection */
|
|
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
|
|
|
|
/* Compute the number of bytes to process */
|
|
H5_ASSIGN_OVERFLOW(max_elem, nelmts, hssize_t, size_t);
|
|
|
|
/* Loop, while elements left in selection */
|
|
while(max_elem > 0) {
|
|
hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
|
|
size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
|
|
size_t nseq; /* Number of sequences generated */
|
|
size_t curr_seq; /* Current sequnce being worked on */
|
|
size_t nelem; /* Number of elements used in sequences */
|
|
|
|
/* Get the sequences of bytes */
|
|
if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
|
|
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
|
|
|
|
/* Loop over sequences */
|
|
for(curr_seq = 0; curr_seq < nseq; curr_seq++) {
|
|
uint8_t *buf; /* Current location in buffer */
|
|
|
|
/* Get offset in memory buffer */
|
|
buf = (uint8_t *)_buf + off[curr_seq];
|
|
|
|
/* Fill each sequence in memory with fill value */
|
|
HDassert((len[curr_seq] % fill_size) == 0);
|
|
H5V_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size));
|
|
} /* end for */
|
|
|
|
/* Decrement number of elements left to process */
|
|
max_elem -= nelem;
|
|
} /* end while */
|
|
|
|
done:
|
|
/* Release resouces */
|
|
if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
|
|
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* H5S_select_fill() */
|
|
|