summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5T.c190
-rw-r--r--src/H5Tconv.c377
-rw-r--r--src/H5Tinit_float.c48
-rw-r--r--src/H5Tmodule.h15
-rw-r--r--src/H5Tnative.c28
-rw-r--r--src/H5Tpkg.h60
-rw-r--r--src/H5Tpublic.h19
-rw-r--r--src/H5private.h20
-rw-r--r--src/H5trace.c8
9 files changed, 721 insertions, 44 deletions
diff --git a/src/H5T.c b/src/H5T.c
index 09eeff8..a340211 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -100,6 +100,30 @@
dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO; \
}
+/* Define the code templates for standard 16-bit floats for the "GUTS" in the H5T_INIT_TYPE macro */
+#define H5T_INIT_TYPE_FLOAT16_COMMON(ENDIANNESS) \
+ { \
+ H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) \
+ dt->shared->u.atomic.u.f.sign = 15; \
+ dt->shared->u.atomic.u.f.epos = 10; \
+ dt->shared->u.atomic.u.f.esize = 5; \
+ dt->shared->u.atomic.u.f.ebias = 0xf; \
+ dt->shared->u.atomic.u.f.mpos = 0; \
+ dt->shared->u.atomic.u.f.msize = 10; \
+ dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ }
+
+#define H5T_INIT_TYPE_FLOAT16LE_CORE \
+ { \
+ H5T_INIT_TYPE_FLOAT16_COMMON(H5T_ORDER_LE) \
+ }
+
+#define H5T_INIT_TYPE_FLOAT16BE_CORE \
+ { \
+ H5T_INIT_TYPE_FLOAT16_COMMON(H5T_ORDER_BE) \
+ }
+
/* Define the code templates for standard floats for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_FLOAT_COMMON(ENDIANNESS) \
{ \
@@ -374,6 +398,8 @@ H5T_order_t H5T_native_order_g = H5T_ORDER_ERROR;
* If more of these are added, the new ones must be added to the list of
* types to reset in H5T_term_package().
*/
+hid_t H5T_IEEE_F16BE_g = FAIL;
+hid_t H5T_IEEE_F16LE_g = FAIL;
hid_t H5T_IEEE_F32BE_g = FAIL;
hid_t H5T_IEEE_F32LE_g = FAIL;
hid_t H5T_IEEE_F64BE_g = FAIL;
@@ -429,6 +455,7 @@ hid_t H5T_NATIVE_LONG_g = FAIL;
hid_t H5T_NATIVE_ULONG_g = FAIL;
hid_t H5T_NATIVE_LLONG_g = FAIL;
hid_t H5T_NATIVE_ULLONG_g = FAIL;
+hid_t H5T_NATIVE_FLOAT16_g = FAIL;
hid_t H5T_NATIVE_FLOAT_g = FAIL;
hid_t H5T_NATIVE_DOUBLE_g = FAIL;
hid_t H5T_NATIVE_LDOUBLE_g = FAIL;
@@ -497,6 +524,7 @@ size_t H5T_NATIVE_LONG_ALIGN_g = 0;
size_t H5T_NATIVE_ULONG_ALIGN_g = 0;
size_t H5T_NATIVE_LLONG_ALIGN_g = 0;
size_t H5T_NATIVE_ULLONG_ALIGN_g = 0;
+size_t H5T_NATIVE_FLOAT16_ALIGN_g = 0;
size_t H5T_NATIVE_FLOAT_ALIGN_g = 0;
size_t H5T_NATIVE_DOUBLE_ALIGN_g = 0;
size_t H5T_NATIVE_LDOUBLE_ALIGN_g = 0;
@@ -532,6 +560,15 @@ size_t H5T_NATIVE_UINT_FAST64_ALIGN_g = 0;
/* Useful floating-point values for conversion routines */
/* (+/- Inf for all floating-point types) */
+#ifdef H5_HAVE__FLOAT16
+/* Initialize these with a float literal since the f16 suffix
+ * is non-standard C and gives warnings when compiling the
+ * library with the -pedantic flag. These values will be
+ * overwritten anyway.
+ */
+H5__Float16 H5T_NATIVE_FLOAT16_POS_INF_g = 0.0f;
+H5__Float16 H5T_NATIVE_FLOAT16_NEG_INF_g = 0.0f;
+#endif
float H5T_NATIVE_FLOAT_POS_INF_g = 0.0F;
float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0F;
double H5T_NATIVE_DOUBLE_POS_INF_g = 0.0;
@@ -684,6 +721,49 @@ H5T__init_inf(void)
} /* end for */
} /* end if */
+#ifdef H5_HAVE__FLOAT16
+ /* Get the _Float16 datatype */
+ if (NULL == (dst_p = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT16_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
+ dst = &dst_p->shared->u.atomic;
+
+ /* Check that we can re-order the bytes correctly */
+ if (H5T_ORDER_LE != H5T_native_order_g && H5T_ORDER_BE != H5T_native_order_g)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+
+ /* +Inf */
+ d = (uint8_t *)&H5T_NATIVE_FLOAT16_POS_INF_g;
+ H5T__bit_set(d, dst->u.f.sign, (size_t)1, false);
+ H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, true);
+ H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, false);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for (u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
+ d[u] = tmp;
+ } /* end for */
+ } /* end if */
+
+ /* -Inf */
+ d = (uint8_t *)&H5T_NATIVE_FLOAT16_NEG_INF_g;
+ H5T__bit_set(d, dst->u.f.sign, (size_t)1, true);
+ H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, true);
+ H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, false);
+
+ /* Swap the bytes if the machine architecture is big-endian */
+ if (H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for (u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
+ d[u] = tmp;
+ } /* end for */
+ } /* end if */
+#endif
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__init_inf() */
@@ -737,6 +817,9 @@ H5T_init(void)
herr_t status;
bool copied_dtype =
true; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
+#ifdef H5_HAVE__FLOAT16
+ H5T_t *native_float16 = NULL; /* Datatype structure for native _Float16 type */
+#endif
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -778,6 +861,10 @@ H5T_init(void)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object");
if (NULL == (native_ullong = (H5T_t *)H5I_object(H5T_NATIVE_ULLONG_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object");
+#ifdef H5_HAVE__FLOAT16
+ if (NULL == (native_float16 = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT16_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object");
+#endif
if (NULL == (native_float = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object");
if (NULL == (native_double = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g)))
@@ -822,6 +909,12 @@ H5T_init(void)
*------------------------------------------------------------
*/
+ /* IEEE 2-byte little-endian float */
+ H5T_INIT_TYPE(FLOAT16LE, H5T_IEEE_F16LE_g, COPY, native_double, SET, 2)
+
+ /* IEEE 2-byte big-endian float */
+ H5T_INIT_TYPE(FLOAT16BE, H5T_IEEE_F16BE_g, COPY, native_double, SET, 2)
+
/* IEEE 4-byte little-endian float */
H5T_INIT_TYPE(FLOATLE, H5T_IEEE_F32LE_g, COPY, native_double, SET, 4)
@@ -1061,6 +1154,20 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "ldbl_flt", native_ldouble, native_float, H5T__conv_ldouble_float);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_dbl", native_ldouble, native_double, H5T__conv_ldouble_double);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "flt16_flt", native_float16, native_float, H5T__conv__Float16_float);
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_dbl", native_float16, native_double,
+ H5T__conv__Float16_double);
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_ldbl", native_float16, native_ldouble,
+ H5T__conv__Float16_ldouble);
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "flt_flt16", native_float, native_float16, H5T__conv_float__Float16);
+ status |= H5T__register_int(H5T_PERS_HARD, "dbl_flt16", native_double, native_float16,
+ H5T__conv_double__Float16);
+ status |= H5T__register_int(H5T_PERS_HARD, "ldbl_flt16", native_ldouble, native_float16,
+ H5T__conv_ldouble__Float16);
+#endif
/* from long long */
status |=
@@ -1219,6 +1326,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "schar_dbl", native_schar, native_double, H5T__conv_schar_double);
status |=
H5T__register_int(H5T_PERS_HARD, "schar_ldbl", native_schar, native_ldouble, H5T__conv_schar_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "schar_flt16", native_schar, native_float16,
+ H5T__conv_schar__Float16);
+#endif
/* From unsigned char to floats */
status |=
@@ -1227,6 +1338,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "uchar_dbl", native_uchar, native_double, H5T__conv_uchar_double);
status |=
H5T__register_int(H5T_PERS_HARD, "uchar_ldbl", native_uchar, native_ldouble, H5T__conv_uchar_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "uchar_flt16", native_uchar, native_float16,
+ H5T__conv_uchar__Float16);
+#endif
/* From short to floats */
status |=
@@ -1235,6 +1350,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "short_dbl", native_short, native_double, H5T__conv_short_double);
status |=
H5T__register_int(H5T_PERS_HARD, "short_ldbl", native_short, native_ldouble, H5T__conv_short_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "short_flt16", native_short, native_float16,
+ H5T__conv_short__Float16);
+#endif
/* From unsigned short to floats */
status |=
@@ -1243,23 +1362,39 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "ushort_dbl", native_ushort, native_double, H5T__conv_ushort_double);
status |= H5T__register_int(H5T_PERS_HARD, "ushort_ldbl", native_ushort, native_ldouble,
H5T__conv_ushort_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "ushort_flt16", native_ushort, native_float16,
+ H5T__conv_ushort__Float16);
+#endif
/* From int to floats */
status |= H5T__register_int(H5T_PERS_HARD, "int_flt", native_int, native_float, H5T__conv_int_float);
status |= H5T__register_int(H5T_PERS_HARD, "int_dbl", native_int, native_double, H5T__conv_int_double);
status |= H5T__register_int(H5T_PERS_HARD, "int_ldbl", native_int, native_ldouble, H5T__conv_int_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "int_flt16", native_int, native_float16, H5T__conv_int__Float16);
+#endif
/* From unsigned int to floats */
status |= H5T__register_int(H5T_PERS_HARD, "uint_flt", native_uint, native_float, H5T__conv_uint_float);
status |= H5T__register_int(H5T_PERS_HARD, "uint_dbl", native_uint, native_double, H5T__conv_uint_double);
status |=
H5T__register_int(H5T_PERS_HARD, "uint_ldbl", native_uint, native_ldouble, H5T__conv_uint_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "uint_flt16", native_uint, native_float16, H5T__conv_uint__Float16);
+#endif
/* From long to floats */
status |= H5T__register_int(H5T_PERS_HARD, "long_flt", native_long, native_float, H5T__conv_long_float);
status |= H5T__register_int(H5T_PERS_HARD, "long_dbl", native_long, native_double, H5T__conv_long_double);
status |=
H5T__register_int(H5T_PERS_HARD, "long_ldbl", native_long, native_ldouble, H5T__conv_long_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "long_flt16", native_long, native_float16, H5T__conv_long__Float16);
+#endif
/* From unsigned long to floats */
status |=
@@ -1268,6 +1403,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "ulong_dbl", native_ulong, native_double, H5T__conv_ulong_double);
status |=
H5T__register_int(H5T_PERS_HARD, "ulong_ldbl", native_ulong, native_ldouble, H5T__conv_ulong_ldouble);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "ulong_flt16", native_ulong, native_float16,
+ H5T__conv_ulong__Float16);
+#endif
/* From long long to floats */
status |=
@@ -1278,6 +1417,10 @@ H5T_init(void)
status |=
H5T__register_int(H5T_PERS_HARD, "llong_ldbl", native_llong, native_ldouble, H5T__conv_llong_ldouble);
#endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "llong_flt16", native_llong, native_float16,
+ H5T__conv_llong__Float16);
+#endif
/* From unsigned long long to floats */
status |=
@@ -1288,6 +1431,10 @@ H5T_init(void)
status |= H5T__register_int(H5T_PERS_HARD, "ullong_ldbl", native_ullong, native_ldouble,
H5T__conv_ullong_ldouble);
#endif /* H5T_CONV_INTERNAL_ULLONG_LDOUBLE */
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "ullong_flt16", native_ullong, native_float16,
+ H5T__conv_ullong__Float16);
+#endif
/* From floats to char */
status |=
@@ -1296,6 +1443,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "dbl_schar", native_double, native_schar, H5T__conv_double_schar);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_schar", native_ldouble, native_schar, H5T__conv_ldouble_schar);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_schar", native_float16, native_schar,
+ H5T__conv__Float16_schar);
+#endif
/* From floats to unsigned char */
status |=
@@ -1304,6 +1455,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "dbl_uchar", native_double, native_uchar, H5T__conv_double_uchar);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_uchar", native_ldouble, native_uchar, H5T__conv_ldouble_uchar);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_uchar", native_float16, native_uchar,
+ H5T__conv__Float16_uchar);
+#endif
/* From floats to short */
status |=
@@ -1312,6 +1467,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "dbl_short", native_double, native_short, H5T__conv_double_short);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_short", native_ldouble, native_short, H5T__conv_ldouble_short);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_short", native_float16, native_short,
+ H5T__conv__Float16_short);
+#endif
/* From floats to unsigned short */
status |=
@@ -1320,23 +1479,39 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "dbl_ushort", native_double, native_ushort, H5T__conv_double_ushort);
status |= H5T__register_int(H5T_PERS_HARD, "ldbl_ushort", native_ldouble, native_ushort,
H5T__conv_ldouble_ushort);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_ushort", native_float16, native_ushort,
+ H5T__conv__Float16_ushort);
+#endif
/* From floats to int */
status |= H5T__register_int(H5T_PERS_HARD, "flt_int", native_float, native_int, H5T__conv_float_int);
status |= H5T__register_int(H5T_PERS_HARD, "dbl_int", native_double, native_int, H5T__conv_double_int);
status |= H5T__register_int(H5T_PERS_HARD, "ldbl_int", native_ldouble, native_int, H5T__conv_ldouble_int);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "flt16_int", native_float16, native_int, H5T__conv__Float16_int);
+#endif
/* From floats to unsigned int */
status |= H5T__register_int(H5T_PERS_HARD, "flt_uint", native_float, native_uint, H5T__conv_float_uint);
status |= H5T__register_int(H5T_PERS_HARD, "dbl_uint", native_double, native_uint, H5T__conv_double_uint);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_uint", native_ldouble, native_uint, H5T__conv_ldouble_uint);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "flt16_uint", native_float16, native_uint, H5T__conv__Float16_uint);
+#endif
/* From floats to long */
status |= H5T__register_int(H5T_PERS_HARD, "flt_long", native_float, native_long, H5T__conv_float_long);
status |= H5T__register_int(H5T_PERS_HARD, "dbl_long", native_double, native_long, H5T__conv_double_long);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_long", native_ldouble, native_long, H5T__conv_ldouble_long);
+#ifdef H5_HAVE__FLOAT16
+ status |=
+ H5T__register_int(H5T_PERS_HARD, "flt16_long", native_float16, native_long, H5T__conv__Float16_long);
+#endif
/* From floats to unsigned long */
status |=
@@ -1345,6 +1520,10 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "dbl_ulong", native_double, native_ulong, H5T__conv_double_ulong);
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_ulong", native_ldouble, native_ulong, H5T__conv_ldouble_ulong);
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_ulong", native_float16, native_ulong,
+ H5T__conv__Float16_ulong);
+#endif
/* From floats to long long */
status |=
@@ -1355,6 +1534,10 @@ H5T_init(void)
status |=
H5T__register_int(H5T_PERS_HARD, "ldbl_llong", native_ldouble, native_llong, H5T__conv_ldouble_llong);
#endif /* H5T_CONV_INTERNAL_LDOUBLE_LLONG */
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_llong", native_float16, native_llong,
+ H5T__conv__Float16_llong);
+#endif
/* From floats to unsigned long long */
status |=
@@ -1365,6 +1548,10 @@ H5T_init(void)
status |= H5T__register_int(H5T_PERS_HARD, "ldbl_ullong", native_ldouble, native_ullong,
H5T__conv_ldouble_ullong);
#endif /* H5T_CONV_INTERNAL_LDOUBLE_ULLONG */
+#ifdef H5_HAVE__FLOAT16
+ status |= H5T__register_int(H5T_PERS_HARD, "flt16_ullong", native_float16, native_ullong,
+ H5T__conv__Float16_ullong);
+#endif
/*
* The special no-op conversion is the fastest, so we list it last. The
@@ -1546,6 +1733,8 @@ H5T_top_term_package(void)
/* Reset all the datatype IDs */
if (H5T_IEEE_F32BE_g > 0) {
+ H5T_IEEE_F16BE_g = FAIL;
+ H5T_IEEE_F16LE_g = FAIL;
H5T_IEEE_F32BE_g = FAIL;
H5T_IEEE_F32LE_g = FAIL;
H5T_IEEE_F64BE_g = FAIL;
@@ -1598,6 +1787,7 @@ H5T_top_term_package(void)
H5T_NATIVE_ULONG_g = FAIL;
H5T_NATIVE_LLONG_g = FAIL;
H5T_NATIVE_ULLONG_g = FAIL;
+ H5T_NATIVE_FLOAT16_g = FAIL;
H5T_NATIVE_FLOAT_g = FAIL;
H5T_NATIVE_DOUBLE_g = FAIL;
H5T_NATIVE_LDOUBLE_g = FAIL;
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 72debe8..33852a9 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -113,6 +113,14 @@
* at least as wide as the destination. Overflow can occur
* when the source magnitude is too large for the destination.
*
+ * fX: Floating-point values to integers where the destination is at least
+ * as wide as the source. This case cannot generate overflows.
+ *
+ * Xf: Integers to floating-point values where the source is at least as
+ * wide as the destination. Overflows can occur when the destination is
+ * narrower than the source.
+ *
+ *
* The macros take a subset of these arguments in the order listed here:
*
* CDATA: A pointer to the H5T_cdata_t structure that was passed to the
@@ -690,6 +698,72 @@
H5T_CONV(H5T_CONV_Fx, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \
} while (0)
+#define H5T_CONV_fX(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ do { \
+ HDcompile_assert(sizeof(ST) <= sizeof(DT)); \
+ H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \
+ } while (0)
+
+#define H5T_CONV_Xf_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \
+ { \
+ if (*(S) > (ST)(D_MAX) || (sprec < dprec && *(S) == (ST)(D_MAX))) { \
+ H5T_conv_ret_t except_ret = \
+ (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, S, D, cb_struct.user_data); \
+ if (except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \
+ else if (except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else if (*(S) < (ST)(D_MIN)) { \
+ H5T_conv_ret_t except_ret = \
+ (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, S, D, cb_struct.user_data); \
+ if (except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \
+ else if (except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else if (sprec > dprec) { \
+ unsigned low_bit_pos, high_bit_pos; \
+ \
+ /* Detect high & low bits set in source */ \
+ H5T_HI_LO_BIT_SET(ST, *(S), low_bit_pos, high_bit_pos) \
+ \
+ /* Check for more bits of precision in src than available in dst */ \
+ if ((high_bit_pos - low_bit_pos) >= dprec) { \
+ H5T_conv_ret_t except_ret = \
+ (cb_struct.func)(H5T_CONV_EXCEPT_PRECISION, src_id, dst_id, S, D, cb_struct.user_data); \
+ if (except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *(D) = (DT)(*(S)); \
+ else if (except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else \
+ *(D) = (DT)(*(S)); \
+ } \
+ else \
+ *(D) = (DT)(*(S)); \
+ }
+#define H5T_CONV_Xf_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \
+ { \
+ if (*(S) > (ST)(D_MAX)) \
+ *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \
+ else if (*(S) < (ST)(D_MIN)) \
+ *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \
+ else \
+ *(D) = (DT)(*(S)); \
+ }
+
+#define H5T_CONV_Xf(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ do { \
+ H5T_CONV(H5T_CONV_Xf, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \
+ } while (0)
+
/* Since all "no exception" cores do the same thing (assign the value in the
* source location to the destination location, using casting), use one "core"
* to do them all.
@@ -7874,6 +7948,227 @@ H5T__conv_ldouble_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t
}
#endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/
+/* Conversions for _Float16 type */
+#ifdef H5_HAVE__FLOAT16
+herr_t
+H5T__conv_schar__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_xF(SCHAR, FLOAT16, signed char, H5__Float16, -, -);
+}
+
+herr_t
+H5T__conv_uchar__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_xF(UCHAR, FLOAT16, unsigned char, H5__Float16, -, -);
+}
+
+herr_t
+H5T__conv_short__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_xF(SHORT, FLOAT16, short, H5__Float16, -, -);
+}
+
+herr_t
+H5T__conv_ushort__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(USHORT, FLOAT16, unsigned short, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_int__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(INT, FLOAT16, int, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_uint__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(UINT, FLOAT16, unsigned int, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_long__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(LONG, FLOAT16, long, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_ulong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(ULONG, FLOAT16, unsigned long, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_llong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(LLONG, FLOAT16, long long, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_ullong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Xf(ULLONG, FLOAT16, unsigned long long, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_float__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Ff(FLOAT, FLOAT16, float, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_double__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Ff(DOUBLE, FLOAT16, double, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv_ldouble__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+ H5T_CONV_Ff(LDOUBLE, FLOAT16, long double, H5__Float16, -FLT16_MAX, FLT16_MAX);
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+}
+
+herr_t
+H5T__conv__Float16_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5_GCC_CLANG_DIAG_OFF("float-equal")
+ H5T_CONV_Fx(FLOAT16, SCHAR, H5__Float16, signed char, SCHAR_MIN, SCHAR_MAX);
+ H5_GCC_CLANG_DIAG_ON("float-equal")
+}
+
+herr_t
+H5T__conv__Float16_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5_GCC_CLANG_DIAG_OFF("float-equal")
+ H5T_CONV_Fx(FLOAT16, UCHAR, H5__Float16, unsigned char, 0, UCHAR_MAX);
+ H5_GCC_CLANG_DIAG_ON("float-equal")
+}
+
+herr_t
+H5T__conv__Float16_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5_GCC_CLANG_DIAG_OFF("float-equal")
+ H5T_CONV_Fx(FLOAT16, SHORT, H5__Float16, short, SHRT_MIN, SHRT_MAX);
+ H5_GCC_CLANG_DIAG_ON("float-equal")
+}
+
+herr_t
+H5T__conv__Float16_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, USHORT, H5__Float16, unsigned short, 0, USHRT_MAX);
+}
+
+herr_t
+H5T__conv__Float16_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, INT, H5__Float16, int, INT_MIN, INT_MAX);
+}
+
+herr_t
+H5T__conv__Float16_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, UINT, H5__Float16, unsigned int, 0, UINT_MAX);
+}
+
+herr_t
+H5T__conv__Float16_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, LONG, H5__Float16, long, LONG_MIN, LONG_MAX);
+}
+
+herr_t
+H5T__conv__Float16_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, ULONG, H5__Float16, unsigned long, 0, ULONG_MAX);
+}
+
+herr_t
+H5T__conv__Float16_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, LLONG, H5__Float16, long long, LLONG_MIN, LLONG_MAX);
+}
+
+herr_t
+H5T__conv__Float16_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fX(FLOAT16, ULLONG, H5__Float16, unsigned long long, 0, ULLONG_MAX);
+}
+
+herr_t
+H5T__conv__Float16_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fF(FLOAT16, FLOAT, H5__Float16, float, -, -);
+}
+
+herr_t
+H5T__conv__Float16_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fF(FLOAT16, DOUBLE, H5__Float16, double, -, -);
+}
+
+herr_t
+H5T__conv__Float16_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
+ size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
+{
+ H5T_CONV_fF(FLOAT16, LDOUBLE, H5__Float16, long double, -, -);
+}
+#endif
+
/*-------------------------------------------------------------------------
* Function: H5T__conv_f_i
*
@@ -7910,8 +8205,9 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
uint8_t *int_buf = NULL; /*buffer for temporary value */
size_t buf_size; /*buffer size for temporary value */
size_t i; /*miscellaneous counters */
- size_t first; /*first bit(MSB) in an integer */
- ssize_t sfirst; /*a signed version of `first' */
+ ssize_t msb_pos_s; /*first bit(MSB) in an integer */
+ ssize_t new_msb_pos; /*MSB position after shifting mantissa by exponent */
+ hssize_t shift_val; /*shift value when shifting mantissa by exponent */
H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */
bool truncated; /*if fraction value is dropped */
bool reverse; /*if reverse order of destination at the end */
@@ -7976,8 +8272,11 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
/* Allocate enough space for the buffer holding temporary
* converted value
*/
- buf_size = (size_t)(pow(2.0, (double)src.u.f.esize) / 8 + 1);
- int_buf = (uint8_t *)H5MM_calloc(buf_size);
+ if (dst.prec / 8 > src_p->shared->size)
+ buf_size = (dst.prec + 7) / 8;
+ else
+ buf_size = src_p->shared->size;
+ int_buf = (uint8_t *)H5MM_calloc(buf_size);
/* Get conversion exception callback property */
if (H5CX_get_dt_conv_cb(&cb_struct) < 0)
@@ -8234,35 +8533,46 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
H5T__bit_inc(int_buf, src.u.f.msize, 8 * buf_size - src.u.f.msize);
/*
+ * What is the bit position for the most significant bit(MSB) of S
+ * which is set? This is checked before shifting and before possibly
+ * converting to a negative integer. Note that later use of this value
+ * assumes that H5T__bit_shift will always shift in 0 during a right
+ * shift.
+ */
+ msb_pos_s = H5T__bit_find(int_buf, (size_t)0, src.prec, H5T_BIT_MSB, true);
+
+ /*
+ * The temporary buffer has no bits set and must therefore be
+ * zero; nothing to do.
+ */
+ if (msb_pos_s < 0)
+ goto padding;
+
+ /*
* Shift mantissa part by exponent minus mantissa size(right shift),
* or by mantissa size minus exponent(left shift). Example: Sequence
* 10...010111, expo=20, expo-msize=-3. Right-shift the sequence, we get
* 00010...10. The last three bits were dropped.
*/
- H5T__bit_shift(int_buf, expo - (ssize_t)src.u.f.msize, (size_t)0, buf_size * 8);
+ shift_val = expo - (ssize_t)src.u.f.msize;
+ H5T__bit_shift(int_buf, shift_val, (size_t)0, buf_size * 8);
+
+ /* Calculate the new position of the MSB after shifting and
+ * skip to the padding section if we shifted exactly to 0
+ * (MSB position is -1)
+ */
+ new_msb_pos = msb_pos_s + shift_val;
+ if (new_msb_pos == -1)
+ goto padding;
/*
- * If expo is less than mantissa size, the frantional value is dropped off
+ * If expo is less than mantissa size, the fractional value is dropped off
* during conversion. Set exception type to be "truncate"
*/
if ((size_t)expo < src.u.f.msize && cb_struct.func)
truncated = true;
- /*
- * What is the bit position for the most significant bit(MSB) of S
- * which is set? This is checked before converted to negative
- * integer.
- */
- sfirst = H5T__bit_find(int_buf, (size_t)0, 8 * buf_size, H5T_BIT_MSB, true);
- first = (size_t)sfirst;
-
- if (sfirst < 0) {
- /*
- * The source has no bits set and must therefore be zero.
- * Set the destination to zero - nothing to do.
- */
- }
- else if (H5T_SGN_NONE == dst.u.i.sign) { /*destination is unsigned*/
+ if (H5T_SGN_NONE == dst.u.i.sign) { /*destination is unsigned*/
/*
* Destination is unsigned. Library's default way: If the source value
* is greater than the maximal destination value then it overflows, the
@@ -8289,7 +8599,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
}
}
else { /*source is positive*/
- if (first >= dst.prec) {
+ if (new_msb_pos >= (ssize_t)dst.prec) {
/*overflow*/
if (cb_struct.func) { /*If user's exception handler is present, use it*/
/*reverse order first*/
@@ -8310,7 +8620,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL,
"can't handle conversion exception");
}
- else if (first < dst.prec) {
+ else {
if (truncated &&
cb_struct.func) { /*If user's exception handler is present, use it*/
/*reverse order first*/
@@ -8320,9 +8630,11 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
src_rev, d, cb_struct.user_data);
}
- if (except_ret == H5T_CONV_UNHANDLED)
+ if (except_ret == H5T_CONV_UNHANDLED) {
/*copy source value into it if case is ignored by user handler*/
- H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, first + 1);
+ if (new_msb_pos >= 0)
+ H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1);
+ }
else if (except_ret == H5T_CONV_HANDLED) {
/*No need to reverse the order of destination because user handles it*/
reverse = false;
@@ -8336,7 +8648,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
}
else if (H5T_SGN_2 == dst.u.i.sign) { /*Destination is signed*/
if (sign) { /*source is negative*/
- if (first < dst.prec - 1) {
+ if ((new_msb_pos >= 0) && ((size_t)new_msb_pos < dst.prec - 1)) {
if (truncated &&
cb_struct.func) { /*If user's exception handler is present, use it*/
/*reverse order first*/
@@ -8348,8 +8660,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
if (except_ret == H5T_CONV_UNHANDLED) { /*If this case ignored by user handler*/
/*Convert to integer representation. Equivalent to ~(value - 1).*/
- H5T__bit_dec(int_buf, (size_t)0, 8 * buf_size);
- H5T__bit_neg(int_buf, (size_t)0, 8 * buf_size);
+ H5T__bit_dec(int_buf, (size_t)0, dst.prec);
+ H5T__bit_neg(int_buf, (size_t)0, dst.prec);
/*copy source value into destination*/
H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, dst.prec - 1);
@@ -8389,7 +8701,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
}
}
else { /*source is positive*/
- if (first >= dst.prec - 1) {
+ if (new_msb_pos >= (ssize_t)dst.prec - 1) {
/*overflow*/
if (cb_struct.func) { /*If user's exception handler is present, use it*/
/*reverse order first*/
@@ -8410,7 +8722,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
goto next;
}
}
- else if (first < dst.prec - 1) {
+ else if (new_msb_pos < (ssize_t)dst.prec - 1) {
if (truncated &&
cb_struct.func) { /*If user's exception handler is present, use it*/
/*reverse order first*/
@@ -8422,7 +8734,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
if (except_ret == H5T_CONV_UNHANDLED) {
/*copy source value into it if case is ignored by user handler*/
- H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, first + 1);
+ if (new_msb_pos >= 0)
+ H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1);
}
else if (except_ret == H5T_CONV_ABORT)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL,
@@ -8601,7 +8914,7 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
/* Allocate enough space for the buffer holding temporary
* converted value
*/
- buf_size = (src.prec > dst.u.f.msize ? src.prec : dst.u.f.msize) / 8 + 1;
+ buf_size = ((src.prec > dst.u.f.msize ? src.prec : dst.u.f.msize) + 7) / 8;
int_buf = (uint8_t *)H5MM_calloc(buf_size);
/* Get conversion exception callback property */
diff --git a/src/H5Tinit_float.c b/src/H5Tinit_float.c
index 3213f00..7ddd65b 100644
--- a/src/H5Tinit_float.c
+++ b/src/H5Tinit_float.c
@@ -53,8 +53,8 @@
* Purpose: This macro takes a floating point type like `double' and
* and detects byte order, mantissa location, exponent location,
* sign bit location, presence or absence of implicit mantissa
- * bit, and exponent bias and initializes a detected_t structure
- * with those properties.
+ * bit, and exponent bias and initializes a H5T_fpoint_det_t
+ * structure with those properties.
*
* Note that these operations can raise floating-point
* exceptions and building with some compiler options
@@ -306,14 +306,17 @@ H5T__fix_order(int n, int last, int *perm, H5T_order_t *order)
if (last <= 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "failed to detect byte order");
- /* We have at least three points to consider */
- if (perm[last] < perm[last - 1] && perm[last - 1] < perm[last - 2]) {
+ if (perm[last] < perm[last - 1] &&
+ /* Only check perm[last - 2] if we have more than 2 points to consider */
+ ((last < 2) || (perm[last - 1] < perm[last - 2]))) {
/* Little endian */
*order = H5T_ORDER_LE;
for (int i = 0; i < n; i++)
perm[i] = i;
}
- else if (perm[last] > perm[last - 1] && perm[last - 1] > perm[last - 2]) {
+ else if (perm[last] > perm[last - 1] &&
+ /* Only check perm[last - 2] if we have more than 2 points to consider */
+ ((last < 2) || (perm[last - 1] > perm[last - 2]))) {
/* Big endian */
*order = H5T_ORDER_BE;
for (int i = 0; i < n; i++)
@@ -358,7 +361,7 @@ done:
* Return: imp_bit will be set to 1 if the most significant bit
* of the mantissa is discarded (ie, the mantissa has an
* implicit `one' as the most significant bit). Otherwise,
- * imp_bit will be set to zero zero.
+ * imp_bit will be set to zero.
*
* SUCCEED/FAIL
*-------------------------------------------------------------------------
@@ -570,6 +573,39 @@ H5T__init_native_float_types(void)
*/
H5T_native_order_g = det.order;
+#ifdef H5_HAVE__FLOAT16
+ /* H5T_NATIVE_FLOAT16 */
+
+ /* Get the type's characteristics */
+ memset(&det, 0, sizeof(H5T_fpoint_det_t));
+ DETECT_F(H5__Float16, det);
+
+ /* Allocate and fill type structure */
+ if (NULL == (dt = H5T__alloc()))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "datatype allocation failed");
+ dt->shared->state = H5T_STATE_IMMUTABLE;
+ dt->shared->type = H5T_FLOAT;
+ dt->shared->size = det.size;
+ dt->shared->u.atomic.order = det.order;
+ dt->shared->u.atomic.offset = det.offset;
+ dt->shared->u.atomic.prec = det.prec;
+ dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO;
+ dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO;
+ dt->shared->u.atomic.u.f.sign = det.sign;
+ dt->shared->u.atomic.u.f.epos = det.epos;
+ dt->shared->u.atomic.u.f.esize = det.esize;
+ dt->shared->u.atomic.u.f.ebias = det.ebias;
+ dt->shared->u.atomic.u.f.mpos = det.mpos;
+ dt->shared->u.atomic.u.f.msize = det.msize;
+ dt->shared->u.atomic.u.f.norm = det.norm;
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;
+
+ /* Register the type and set global variables */
+ if ((H5T_NATIVE_FLOAT16_g = H5I_register(H5I_DATATYPE, dt, false)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't register ID for built-in datatype");
+ H5T_NATIVE_FLOAT16_ALIGN_g = det.comp_align;
+#endif
+
done:
/* Clear any FE_INVALID exceptions from NaN handling */
if (feclearexcept(FE_INVALID) != 0)
diff --git a/src/H5Tmodule.h b/src/H5Tmodule.h
index f1b7b17..3654025 100644
--- a/src/H5Tmodule.h
+++ b/src/H5Tmodule.h
@@ -712,6 +712,14 @@
* </tr>
* <tr>
* <td>
+ * #H5T_NATIVE_FLOAT16
+ * </td>
+ * <td span='3'>
+ * _Float16
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>
* #H5T_NATIVE_FLOAT
* </td>
* <td span='3'>
@@ -3753,10 +3761,11 @@ filled according to the value of this property. The padding can be:
* H5T_NATIVE_INT | H5T_NATIVE_UINT |
* H5T_NATIVE_LONG | H5T_NATIVE_ULONG |
* H5T_NATIVE_LLONG | H5T_NATIVE_ULLONG
- * <float> ::= H5T_IEEE_F32BE | H5T_IEEE_F32LE |
+ * <float> ::= H5T_IEEE_F16BE | H5T_IEEE_F16LE |
+ * H5T_IEEE_F32BE | H5T_IEEE_F32LE |
* H5T_IEEE_F64BE | H5T_IEEE_F64LE |
- * H5T_NATIVE_FLOAT | H5T_NATIVE_DOUBLE |
- * H5T_NATIVE_LDOUBLE
+ * H5T_NATIVE_FLOAT16 | H5T_NATIVE_FLOAT |
+ * H5T_NATIVE_DOUBLE | H5T_NATIVE_LDOUBLE
* <time> ::= H5T_TIME: not yet implemented
* <string> ::= H5T_STRING {
* STRSIZE <strsize> ;
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index f83e9c3..8136f96 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -50,6 +50,7 @@ static herr_t H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_siz
* H5T_NATIVE_LONG H5T_NATIVE_ULONG
* H5T_NATIVE_LLONG H5T_NATIVE_ULLONG
*
+ * H5T_NATIVE_FLOAT16 (if available)
* H5T_NATIVE_FLOAT
* H5T_NATIVE_DOUBLE
* H5T_NATIVE_LDOUBLE
@@ -703,6 +704,7 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali
size_t align = 0; /* Alignment necessary for native datatype */
size_t native_size = 0; /* Datatype size of the native type */
enum match_type { /* The different kinds of floating point types we can match */
+ H5T_NATIVE_FLOAT_MATCH_FLOAT16,
H5T_NATIVE_FLOAT_MATCH_FLOAT,
H5T_NATIVE_FLOAT_MATCH_DOUBLE,
H5T_NATIVE_FLOAT_MATCH_LDOUBLE,
@@ -715,7 +717,14 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali
assert(size > 0);
if (direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) {
- if (size <= sizeof(float)) {
+#ifdef H5_HAVE__FLOAT16
+ if (size <= sizeof(H5__Float16)) {
+ match = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
+ native_size = sizeof(H5__Float16);
+ }
+ else
+#endif
+ if (size <= sizeof(float)) {
match = H5T_NATIVE_FLOAT_MATCH_FLOAT;
native_size = sizeof(float);
}
@@ -741,14 +750,29 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali
match = H5T_NATIVE_FLOAT_MATCH_DOUBLE;
native_size = sizeof(double);
}
- else {
+ else
+#ifdef H5_HAVE__FLOAT16
+ if (size > sizeof(H5__Float16))
+#endif
+ {
match = H5T_NATIVE_FLOAT_MATCH_FLOAT;
native_size = sizeof(float);
}
+#ifdef H5_HAVE__FLOAT16
+ else {
+ match = H5T_NATIVE_FLOAT_MATCH_FLOAT16;
+ native_size = sizeof(H5__Float16);
+ }
+#endif
}
/* Set the appropriate native floating point information */
switch (match) {
+ case H5T_NATIVE_FLOAT_MATCH_FLOAT16:
+ tid = H5T_NATIVE_FLOAT16;
+ align = H5T_NATIVE_FLOAT16_ALIGN_g;
+ break;
+
case H5T_NATIVE_FLOAT_MATCH_FLOAT:
tid = H5T_NATIVE_FLOAT;
align = H5T_NATIVE_FLOAT_ALIGN_g;
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index ef5ba36..8f063b9 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -416,6 +416,7 @@ H5_DLLVAR size_t H5T_NATIVE_LONG_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_ULONG_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_LLONG_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_ULLONG_ALIGN_g;
+H5_DLLVAR size_t H5T_NATIVE_FLOAT16_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_FLOAT_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_DOUBLE_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_ALIGN_g;
@@ -451,6 +452,10 @@ H5_DLLVAR size_t H5T_NATIVE_UINT_FAST64_ALIGN_g;
/* Useful floating-point values for conversion routines */
/* (+/- Inf for all floating-point types) */
+#ifdef H5_HAVE__FLOAT16
+H5_DLLVAR H5__Float16 H5T_NATIVE_FLOAT16_POS_INF_g;
+H5_DLLVAR H5__Float16 H5T_NATIVE_FLOAT16_NEG_INF_g;
+#endif
H5_DLLVAR float H5T_NATIVE_FLOAT_POS_INF_g;
H5_DLLVAR float H5T_NATIVE_FLOAT_NEG_INF_g;
H5_DLLVAR double H5T_NATIVE_DOUBLE_POS_INF_g;
@@ -831,6 +836,61 @@ H5_DLL herr_t H5T__conv_ldouble_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *c
H5_DLL herr_t H5T__conv_ldouble_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+#ifdef H5_HAVE__FLOAT16
+H5_DLL herr_t H5T__conv_schar__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_uchar__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_short__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_ushort__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_int__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_uint__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_long__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_ulong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_llong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_ullong__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_float__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_double__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv_ldouble__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+H5_DLL herr_t H5T__conv__Float16_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+#endif
+
/* Bit twiddling functions */
H5_DLL void H5T__bit_copy(uint8_t *dst, size_t dst_offset, const uint8_t *src, size_t src_offset,
size_t size);
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index a117075..cfeb384 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -251,6 +251,16 @@ typedef H5T_conv_ret_t (*H5T_conv_except_func_t)(H5T_conv_except_t except_type,
*/
/**
* \ingroup PDTIEEE
+ * 16-bit big-endian IEEE floating-point numbers
+ */
+#define H5T_IEEE_F16BE (H5OPEN H5T_IEEE_F16BE_g)
+/**
+ * \ingroup PDTIEEE
+ * 16-bit little-endian IEEE floating-point numbers
+ */
+#define H5T_IEEE_F16LE (H5OPEN H5T_IEEE_F16LE_g)
+/**
+ * \ingroup PDTIEEE
* 32-bit big-endian IEEE floating-point numbers
*/
#define H5T_IEEE_F32BE (H5OPEN H5T_IEEE_F32BE_g)
@@ -269,6 +279,8 @@ typedef H5T_conv_ret_t (*H5T_conv_except_func_t)(H5T_conv_except_t except_type,
* 64-bit little-endian IEEE floating-point numbers
*/
#define H5T_IEEE_F64LE (H5OPEN H5T_IEEE_F64LE_g)
+H5_DLLVAR hid_t H5T_IEEE_F16BE_g;
+H5_DLLVAR hid_t H5T_IEEE_F16LE_g;
H5_DLLVAR hid_t H5T_IEEE_F32BE_g;
H5_DLLVAR hid_t H5T_IEEE_F32LE_g;
H5_DLLVAR hid_t H5T_IEEE_F64BE_g;
@@ -792,6 +804,11 @@ H5_DLLVAR hid_t H5T_VAX_F64_g;
#define H5T_NATIVE_ULLONG (H5OPEN H5T_NATIVE_ULLONG_g)
/**
* \ingroup PDTNAT
+ * C-style \Code{_Float16}
+ */
+#define H5T_NATIVE_FLOAT16 (H5OPEN H5T_NATIVE_FLOAT16_g)
+/**
+ * \ingroup PDTNAT
* C-style \Code{float}
*/
#define H5T_NATIVE_FLOAT (H5OPEN H5T_NATIVE_FLOAT_g)
@@ -865,6 +882,7 @@ H5_DLLVAR hid_t H5T_NATIVE_LONG_g;
H5_DLLVAR hid_t H5T_NATIVE_ULONG_g;
H5_DLLVAR hid_t H5T_NATIVE_LLONG_g;
H5_DLLVAR hid_t H5T_NATIVE_ULLONG_g;
+H5_DLLVAR hid_t H5T_NATIVE_FLOAT16_g;
H5_DLLVAR hid_t H5T_NATIVE_FLOAT_g;
H5_DLLVAR hid_t H5T_NATIVE_DOUBLE_g;
H5_DLLVAR hid_t H5T_NATIVE_LDOUBLE_g;
@@ -2319,6 +2337,7 @@ H5_DLL htri_t H5Tis_variable_str(hid_t type_id);
* \li #H5T_NATIVE_ULONG
* \li #H5T_NATIVE_ULLONG
*
+ * \li #H5T_NATIVE_FLOAT16 (if available)
* \li #H5T_NATIVE_FLOAT
* \li #H5T_NATIVE_DOUBLE
* \li #H5T_NATIVE_LDOUBLE
diff --git a/src/H5private.h b/src/H5private.h
index 5663c00..0cbda2e 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -27,7 +27,6 @@
#include <errno.h>
#include <fcntl.h>
#include <fenv.h>
-#include <float.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
@@ -36,6 +35,10 @@
#include <string.h>
#include <time.h>
+/* Define __STDC_WANT_IEC_60559_TYPES_EXT__ for _FloatN support, if available */
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
/* POSIX headers */
#ifdef H5_HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -540,6 +543,21 @@
#define H5_GCC_CLANG_DIAG_ON(x)
#endif
+/* Create a typedef for library usage of the _Float16 type
+ * to avoid issues when compiling the library with the
+ * -pedantic flag or similar where we get warnings about
+ * _Float16 not being an ISO C type.
+ */
+#ifdef H5_HAVE__FLOAT16
+#if defined(__GNUC__)
+__extension__ typedef _Float16 H5__Float16;
+#elif defined(__clang__)
+/* TODO */
+#else
+typedef _Float16 H5__Float16;
+#endif
+#endif
+
/* Function pointer typedef for qsort */
typedef int (*H5_sort_func_cb_t)(const void *, const void *);
diff --git a/src/H5trace.c b/src/H5trace.c
index 7657356..37f45fc 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -1625,12 +1625,20 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5T_NATIVE_LLONG");
else if (obj == H5T_NATIVE_ULLONG_g)
H5RS_acat(rs, "H5T_NATIVE_ULLONG");
+#ifdef H5_HAVE__FLOAT16
+ else if (obj == H5T_NATIVE_FLOAT16_g)
+ H5RS_acat(rs, "H5T_NATIVE_FLOAT16");
+#endif
else if (obj == H5T_NATIVE_FLOAT_g)
H5RS_acat(rs, "H5T_NATIVE_FLOAT");
else if (obj == H5T_NATIVE_DOUBLE_g)
H5RS_acat(rs, "H5T_NATIVE_DOUBLE");
else if (obj == H5T_NATIVE_LDOUBLE_g)
H5RS_acat(rs, "H5T_NATIVE_LDOUBLE");
+ else if (obj == H5T_IEEE_F16BE_g)
+ H5RS_acat(rs, "H5T_IEEE_F16BE");
+ else if (obj == H5T_IEEE_F16LE_g)
+ H5RS_acat(rs, "H5T_IEEE_F16LE");
else if (obj == H5T_IEEE_F32BE_g)
H5RS_acat(rs, "H5T_IEEE_F32BE");
else if (obj == H5T_IEEE_F32LE_g)