summaryrefslogtreecommitdiffstats
path: root/src/H5Tconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r--src/H5Tconv.c258
1 files changed, 156 insertions, 102 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 05187b9..2ba0e32 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -17,14 +17,19 @@
/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
- intn *src2dst; /*mapping from src to dst memb ID */
+ intn *src2dst; /*mapping from src to dst member num */
hid_t *src_memb_id; /*source member type ID's */
hid_t *dst_memb_id; /*destination member type ID's */
- H5T_conv_t *memb_conv; /*array of membr conversion functions*/
- H5T_cdata_t **memb_cdata; /*array of member cdata pointers */
+ H5T_path_t **memb_path; /*conversion path for each member */
size_t *memb_nelmts; /*member element count */
} H5T_conv_struct_t;
+/* Conversion data for the hardware conversion functions */
+typedef struct H5T_conv_hw_t {
+ hsize_t s_aligned; /*number source elements aligned */
+ hsize_t d_aligned; /*number destination elements aligned*/
+} H5T_conv_hw_t;
+
/* Interface initialization */
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
@@ -253,33 +258,47 @@ static intn interface_initialize_g = 0;
size_t elmtno; /*element number */ \
ST *src, *s; /*source buffer */ \
DT *dst, *d; /*destination buffer */ \
- H5T_t *st, *dt; /*src and dest data types */ \
+ H5T_t *st, *dt; /*data type descriptors */ \
long_long aligned; /*largest integer type, aligned */ \
hbool_t s_mv, d_mv; /*move data to align it? */ \
+ size_t dt_size=sizeof(DT); /*needed by CI_END macro */ \
+ H5T_conv_hw_t *priv = cdata->priv; /*private data */ \
\
switch (cdata->command) { \
case H5T_CONV_INIT: \
cdata->need_bkg = H5T_BKG_NO; \
+ if (NULL==(st=H5I_object(src_id)) || \
+ NULL==(dt=H5I_object(dst_id))) { \
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
+ "unable to dereference data type object ID"); \
+ } \
+ if (st->size!=sizeof(ST) || dt->size!=sizeof(DT)) { \
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
+ "disagreement about data type size"); \
+ } \
+ if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) { \
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "memory allocation failed"); \
+ } \
break; \
case H5T_CONV_FREE: \
+ CI_PRINT_STATS(STYPE,DTYPE); \
+ cdata->priv = H5MM_xfree(cdata->priv); \
break; \
case H5T_CONV_CONV: \
src = (ST*)buf+(STRT); \
dst = (DT*)buf+(STRT); \
- st = H5I_object(src_id); \
- dt = H5I_object(dst_id); \
- assert(st && dt); \
s_mv = H5T_NATIVE_##STYPE##_ALIGN_g>1 && \
((size_t)buf%H5T_NATIVE_##STYPE##_ALIGN_g || \
- st->size%H5T_NATIVE_##STYPE##_ALIGN_g); \
+ sizeof(ST)%H5T_NATIVE_##STYPE##_ALIGN_g); \
d_mv = H5T_NATIVE_##DTYPE##_ALIGN_g>1 && \
((size_t)buf%H5T_NATIVE_##DTYPE##_ALIGN_g || \
- dt->size%H5T_NATIVE_##DTYPE##_ALIGN_g); \
- CI_DEBUG(s_mv, STYPE, ST); \
- CI_DEBUG(d_mv, DTYPE, DT); \
+ sizeof(DT)%H5T_NATIVE_##DTYPE##_ALIGN_g); \
+ if (s_mv) priv->s_aligned += nelmts; \
+ if (d_mv) priv->d_aligned += nelmts; \
for (elmtno=0; elmtno<nelmts; elmtno++, DIR src, DIR dst) { \
if (s_mv) { \
- memcpy(&aligned, src, st->size); \
+ memcpy(&aligned, src, sizeof(ST)); \
s = (ST*)&aligned; \
} else { \
s = src; \
@@ -291,7 +310,7 @@ static intn interface_initialize_g = 0;
}
/* ... user-defined stuff here ... */
#define CI_END \
- if (d_mv) memcpy(dst, &aligned, dt->size); \
+ if (d_mv) memcpy(dst, &aligned, dt_size); \
} \
break; \
default: \
@@ -300,16 +319,24 @@ static intn interface_initialize_g = 0;
} \
}
-/* Print alignment information */
+/* Print alignment statistics */
#ifdef H5T_DEBUG
-# define CI_DEBUG(MV,HDF_TYPE,C_TYPE) { \
- if (MV && H5DEBUG(T)) { \
- fprintf(H5DEBUG(T), "<%d-byte alignment for %s>", \
- H5T_NATIVE_##HDF_TYPE##_ALIGN_g, #C_TYPE); \
+# define CI_PRINT_STATS(STYPE,DTYPE) { \
+ if (H5DEBUG(T) && priv->s_aligned) { \
+ HDfprintf(H5DEBUG(T), \
+ " %Hu src elements aligned on %lu-byte boundaries\n", \
+ priv->s_aligned, \
+ (unsigned long)H5T_NATIVE_##STYPE##_ALIGN_g); \
+ } \
+ if (H5DEBUG(T) && priv->d_aligned) { \
+ HDfprintf(H5DEBUG(T), \
+ " %Hu dst elements aligned on %lu-byte boundaries\n", \
+ priv->d_aligned, \
+ (unsigned long)H5T_NATIVE_##DTYPE##_ALIGN_g); \
} \
}
#else
-# define CI_DEBUG(MV,HDF_TYPE,C_TYPE) /*void*/
+# define CI_PRINT_STATS /*void*/
#endif
/*-------------------------------------------------------------------------
@@ -344,7 +371,6 @@ H5T_conv_noop(hid_t __unused__ src_id, hid_t __unused__ dst_id,
break;
case H5T_CONV_FREE:
- cdata->stats = H5MM_xfree (cdata->stats);
break;
default:
@@ -467,6 +493,16 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* already initialized then the member conversion functions
* are recalculated.
*
+ * Priv fields are indexed by source member number or
+ * destination member number depending on whether the field
+ * contains information about the source data type or the
+ * destination data type (fields that contains the same
+ * information for both source and destination are indexed by
+ * source member number). The src2dst[] priv array maps source
+ * member numbers to destination member numbers, but if the
+ * source member doesn't have a corresponding destination member
+ * then the src2dst[i]=-1.
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
@@ -488,26 +524,21 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
if (!priv) {
/*
- * Notice: the thing marked with `!' below really is `dst' and not
- * `src' because we're only interested in the members of the
- * source type that are also in the destination type.
+ * Allocate private data structure and arrays.
*/
- cdata->priv = priv = H5MM_calloc (sizeof(H5T_conv_struct_t));
- if (NULL==priv) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- priv->src2dst = H5MM_malloc (src->u.compnd.nmembs * sizeof(intn));
- priv->src_memb_id = H5MM_malloc (/*!*/dst->u.compnd.nmembs *
- sizeof(hid_t));
- priv->dst_memb_id = H5MM_malloc (dst->u.compnd.nmembs *
- sizeof(hid_t));
- if (NULL==priv->src2dst ||
- NULL==priv->src_memb_id ||
- NULL==priv->dst_memb_id) {
+ if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(H5T_conv_struct_t))) ||
+ NULL==(priv->src2dst=H5MM_malloc(src->u.compnd.nmembs *
+ sizeof(intn))) ||
+ NULL==(priv->src_memb_id=H5MM_malloc(src->u.compnd.nmembs *
+ sizeof(hid_t))) ||
+ NULL==(priv->dst_memb_id=H5MM_malloc(dst->u.compnd.nmembs *
+ sizeof(hid_t))) ||
+ NULL==(priv->memb_nelmts=H5MM_malloc(src->u.compnd.nmembs *
+ sizeof(size_t)))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
+ src2dst = priv->src2dst;
/*
* Insure that members are sorted.
@@ -523,25 +554,25 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
* member data type conversion functions later.
*/
for (i=0; i<src->u.compnd.nmembs; i++) {
- priv->src2dst[i] = -1;
+ src2dst[i] = -1;
for (j=0; j<dst->u.compnd.nmembs; j++) {
if (!HDstrcmp (src->u.compnd.memb[i].name,
- dst->u.compnd.memb[j].name)) {
- priv->src2dst[i] = j;
+ dst->u.compnd.memb[j].name)) {
+ src2dst[i] = j;
break;
}
}
- if (priv->src2dst[i]>=0) {
+ if (src2dst[i]>=0) {
type = H5T_copy (src->u.compnd.memb[i].type, H5T_COPY_ALL);
tid = H5I_register (H5I_DATATYPE, type);
assert (tid>=0);
- priv->src_memb_id[priv->src2dst[i]] = tid;
+ priv->src_memb_id[i] = tid;
- type = H5T_copy (dst->u.compnd.memb[priv->src2dst[i]].type,
+ type = H5T_copy (dst->u.compnd.memb[src2dst[i]].type,
H5T_COPY_ALL);
tid = H5I_register (H5I_DATATYPE, type);
assert (tid>=0);
- priv->dst_memb_id[priv->src2dst[i]] = tid;
+ priv->dst_memb_id[src2dst[i]] = tid;
}
}
@@ -550,9 +581,9 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
* the same size and shape arrays.
*/
for (i=0; i<src->u.compnd.nmembs; i++) {
- if (priv->src2dst[i]>=0) {
+ if (src2dst[i]>=0) {
H5T_member_t *src_memb = src->u.compnd.memb + i;
- H5T_member_t *dst_memb = dst->u.compnd.memb + priv->src2dst[i];
+ H5T_member_t *dst_memb = dst->u.compnd.memb + src2dst[i];
if (src_memb->ndims != dst_memb->ndims) {
HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"source and dest members have incompatible "
@@ -576,7 +607,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
}
/* Calculate number of elements of each member */
- priv->memb_nelmts = H5MM_malloc(src->u.compnd.nmembs*sizeof(size_t));
for (i=0; i<src->u.compnd.nmembs; i++) {
priv->memb_nelmts[i] = 1;
for (j=0; j<src->u.compnd.memb[i].ndims; j++) {
@@ -589,34 +619,30 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
* (Re)build the cache of member conversion functions and pointers to
* their cdata entries.
*/
- priv->memb_conv = H5MM_xfree (priv->memb_conv);
- priv->memb_cdata = H5MM_xfree (priv->memb_cdata);
- priv->memb_conv = H5MM_malloc (dst->u.compnd.nmembs *
- sizeof(H5T_conv_t));
- priv->memb_cdata = H5MM_calloc (dst->u.compnd.nmembs *
- sizeof(H5T_cdata_t*));
- if (NULL==priv->memb_conv || NULL==priv->memb_cdata) {
+ src2dst = priv->src2dst;
+ H5MM_xfree(priv->memb_path);
+ if (NULL==(priv->memb_path=H5MM_malloc(src->u.compnd.nmembs *
+ sizeof(H5T_path_t*)))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
- src2dst = priv->src2dst;
for (i=0; i<src->u.compnd.nmembs; i++) {
- if (priv->src2dst[i]>=0) {
- H5T_conv_t tconv_func;
- tconv_func = H5T_find(src->u.compnd.memb[i].type,
+ if (src2dst[i]>=0) {
+ H5T_path_t *tpath;
+ tpath = H5T_path_find(src->u.compnd.memb[i].type,
dst->u.compnd.memb[src2dst[i]].type,
- H5T_BKG_NO, priv->memb_cdata+src2dst[i]);
- if (!tconv_func) {
- H5MM_xfree (priv->src2dst);
- H5MM_xfree (priv->src_memb_id);
- H5MM_xfree (priv->dst_memb_id);
- H5MM_xfree (priv->memb_conv);
+ NULL, NULL);
+ if (NULL==(priv->memb_path[i] = tpath)) {
+ H5MM_xfree(priv->src2dst);
+ H5MM_xfree(priv->src_memb_id);
+ H5MM_xfree(priv->dst_memb_id);
+ H5MM_xfree(priv->memb_path);
+ H5MM_xfree(priv->memb_nelmts);
cdata->priv = priv = H5MM_xfree (priv);
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unable to convert member data type");
}
- priv->memb_conv[src2dst[i]] = tconv_func;
}
}
@@ -701,8 +727,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5MM_xfree(priv->src2dst);
H5MM_xfree(priv->src_memb_id);
H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_conv);
- H5MM_xfree(priv->memb_cdata);
+ H5MM_xfree(priv->memb_path);
H5MM_xfree(priv->memb_nelmts);
cdata->priv = priv = H5MM_xfree (priv);
break;
@@ -761,20 +786,21 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
dst_memb = dst->u.compnd.memb + src2dst[i];
if (dst_memb->size <= src_memb->size) {
- H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
- H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
- memb_cdata->command = H5T_CONV_CONV;
- (tconv_func)(priv->src_memb_id[src2dst[i]],
- priv->dst_memb_id[src2dst[i]],
- memb_cdata, priv->memb_nelmts[i],
- buf + src_memb->offset,
- bkg + dst_memb->offset);
-
- HDmemmove (buf + offset, buf + src_memb->offset,
+ if (H5T_convert(priv->memb_path[i],
+ priv->src_memb_id[i],
+ priv->dst_memb_id[src2dst[i]],
+ priv->memb_nelmts[i],
+ buf + src_memb->offset,
+ bkg + dst_memb->offset)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to convert compound data type "
+ "member");
+ }
+ HDmemmove (buf+offset, buf+src_memb->offset,
dst_memb->size);
offset += dst_memb->size;
} else {
- HDmemmove (buf + offset, buf + src_memb->offset,
+ HDmemmove (buf+offset, buf+src_memb->offset,
src_memb->size);
offset += src_memb->size;
}
@@ -793,14 +819,16 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
dst_memb = dst->u.compnd.memb + src2dst[i];
if (dst_memb->size > src_memb->size) {
- H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
- H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
offset -= src_memb->size;
- memb_cdata->command = H5T_CONV_CONV;
- (tconv_func)(priv->src_memb_id[src2dst[i]],
- priv->dst_memb_id[src2dst[i]],
- memb_cdata, priv->memb_nelmts[i],
- buf+offset, bkg+dst_memb->offset);
+ if (H5T_convert(priv->memb_path[i],
+ priv->src_memb_id[i],
+ priv->dst_memb_id[src2dst[i]],
+ priv->memb_nelmts[i],
+ buf+offset, bkg+dst_memb->offset)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to convert compound data type "
+ "member");
+ }
} else {
offset -= dst_memb->size;
}
@@ -4327,44 +4355,57 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
H5T_t *st, *dt; /*type descriptors */
hbool_t src_mv, dst_mv; /*align data? */
double aligned; /*aligned data */
+ H5T_conv_hw_t *priv = cdata->priv; /*private data */
FUNC_ENTER (H5T_conv_float_double, FAIL);
switch (cdata->command) {
case H5T_CONV_INIT:
cdata->need_bkg = H5T_BKG_NO;
+ if (NULL==(st=H5I_object(src_id)) ||
+ NULL==(dt=H5I_object(dst_id))) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to dereference data type object ID");
+ }
+ if (st->size!=sizeof(float) || dt->size!=sizeof(double)) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "disagreement about data type size");
+ }
+ if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ }
break;
case H5T_CONV_FREE:
+ CI_PRINT_STATS(FLOAT, DOUBLE);
+ cdata->priv = H5MM_xfree(cdata->priv);
break;
case H5T_CONV_CONV:
src = (float*)buf + nelmts-1;
dst = (double*)buf + nelmts-1;
- st = H5I_object(src_id);
- dt = H5I_object(dst_id);
- assert(st && dt);
/* Need alignment? */
if (H5T_NATIVE_FLOAT_ALIGN_g>1) {
src_mv = ((size_t)buf % H5T_NATIVE_FLOAT_ALIGN_g) ||
- (st->size % H5T_NATIVE_FLOAT_ALIGN_g);
+ (sizeof(float) % H5T_NATIVE_FLOAT_ALIGN_g);
} else {
src_mv = FALSE;
}
if (H5T_NATIVE_DOUBLE_ALIGN_g>1) {
dst_mv = ((size_t)buf % H5T_NATIVE_DOUBLE_ALIGN_g) ||
- (dt->size % H5T_NATIVE_DOUBLE_ALIGN_g);
+ (sizeof(double) % H5T_NATIVE_DOUBLE_ALIGN_g);
} else {
dst_mv = FALSE;
}
- CI_DEBUG(src_mv, FLOAT, float);
- CI_DEBUG(dst_mv, DOUBLE, double);
+ if (src_mv) priv->s_aligned += nelmts;
+ if (dst_mv) priv->d_aligned += nelmts;
for (elmtno=0; elmtno<nelmts; elmtno++, --src, --dst) {
/* Align source and/or destination */
if (src_mv) {
- memcpy(&aligned, src, st->size);
+ memcpy(&aligned, src, sizeof(float));
s = (float*)&aligned;
} else {
s = src;
@@ -4376,7 +4417,7 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
*d = *s;
/* Unalign destination */
- if (dst_mv) memcpy(dst, &aligned, dt->size);
+ if (dst_mv) memcpy(dst, &aligned, sizeof(double));
}
break;
@@ -4417,44 +4458,57 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
H5T_t *st, *dt; /*type descriptors */
hbool_t src_mv, dst_mv; /*align data? */
double aligned; /*aligned data */
+ H5T_conv_hw_t *priv = cdata->priv; /*private data */
FUNC_ENTER (H5T_conv_double_float, FAIL);
switch (cdata->command) {
case H5T_CONV_INIT:
cdata->need_bkg = H5T_BKG_NO;
+ if (NULL==(st=H5I_object(src_id)) ||
+ NULL==(dt=H5I_object(dst_id))) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to dereference data type object ID");
+ }
+ if (st->size!=sizeof(double) || dt->size!=sizeof(float)) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "disagreement about data type size");
+ }
+ if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ }
break;
case H5T_CONV_FREE:
+ CI_PRINT_STATS(DOUBLE, FLOAT);
+ cdata->priv = H5MM_xfree(cdata->priv);
break;
case H5T_CONV_CONV:
src = (double*)buf;
dst = (float*)buf;
- st = H5I_object(src_id);
- dt = H5I_object(dst_id);
- assert(st && dt);
/* Need alignment? */
if (H5T_NATIVE_DOUBLE_ALIGN_g>1) {
src_mv = ((size_t)buf % H5T_NATIVE_DOUBLE_ALIGN_g) ||
- (st->size % H5T_NATIVE_DOUBLE_ALIGN_g);
+ (sizeof(double) % H5T_NATIVE_DOUBLE_ALIGN_g);
} else {
src_mv = FALSE;
}
if (H5T_NATIVE_FLOAT_ALIGN_g>1) {
dst_mv = ((size_t)buf % H5T_NATIVE_FLOAT_ALIGN_g) ||
- (dt->size % H5T_NATIVE_FLOAT_ALIGN_g);
+ (sizeof(float) % H5T_NATIVE_FLOAT_ALIGN_g);
} else {
dst_mv = FALSE;
}
- CI_DEBUG(src_mv, DOUBLE, double);
- CI_DEBUG(dst_mv, FLOAT, float);
+ if (src_mv) priv->s_aligned += nelmts;
+ if (dst_mv) priv->d_aligned += nelmts;
for (elmtno=0; elmtno<nelmts; elmtno++, src++, dst++) {
/* Align source and/or destination */
if (src_mv) {
- memcpy(&aligned, src, st->size);
+ memcpy(&aligned, src, sizeof(double));
s = (double*)&aligned;
} else {
s = src;
@@ -4478,7 +4532,7 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
}
/* Unalign destination */
- if (dst_mv) memcpy(dst, &aligned, dt->size);
+ if (dst_mv) memcpy(dst, &aligned, sizeof(float));
}
break;