summaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/h5diff_array.c265
-rw-r--r--tools/lib/h5diff_util.c10
-rw-r--r--tools/lib/h5tools_dump.c10
-rw-r--r--tools/lib/h5tools_str.c12
-rw-r--r--tools/lib/h5tools_type.c8
5 files changed, 274 insertions, 31 deletions
diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c
index d8c9ac6..86d873d 100644
--- a/tools/lib/h5diff_array.c
+++ b/tools/lib/h5diff_array.c
@@ -145,6 +145,10 @@ static hsize_t diff_double_element(unsigned char *mem1, unsigned char *mem2, hsi
diff_opt_t *opts);
static hsize_t diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx,
diff_opt_t *opts);
+#ifdef H5_HAVE__FLOAT16
+static hsize_t diff_float16_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx,
+ diff_opt_t *opts);
+#endif
static hsize_t diff_schar_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx,
diff_opt_t *opts);
static hsize_t diff_uchar_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx,
@@ -233,7 +237,20 @@ diff_array(void *_mem1, void *_mem2, diff_opt_t *opts, hid_t container1_id, hid_
*/
case H5T_FLOAT:
H5TOOLS_DEBUG("type_class:H5T_FLOAT");
- if (H5Tequal(opts->m_tid, H5T_NATIVE_FLOAT)) {
+#ifdef H5_HAVE__FLOAT16
+ if (H5Tequal(opts->m_tid, H5T_NATIVE_FLOAT16)) {
+ for (i = 0; i < opts->hs_nelmts; i++) {
+ nfound += diff_float16_element(mem1, mem2, i, opts);
+
+ mem1 += sizeof(H5__Float16);
+ mem2 += sizeof(H5__Float16);
+ if (opts->count_bool && nfound >= opts->count)
+ return nfound;
+ }
+ }
+ else
+#endif
+ if (H5Tequal(opts->m_tid, H5T_NATIVE_FLOAT)) {
for (i = 0; i < opts->hs_nelmts; i++) {
nfound += diff_float_element(mem1, mem2, i, opts);
@@ -263,6 +280,7 @@ diff_array(void *_mem1, void *_mem2, diff_opt_t *opts, hid_t container1_id, hid_
return nfound;
} /* nelmts */
}
+
break;
case H5T_INTEGER:
@@ -1221,38 +1239,50 @@ diff_datum(void *_mem1, void *_mem2, hsize_t elemtno, diff_opt_t *opts, hid_t co
*-------------------------------------------------------------------------
*/
case H5T_FLOAT:
- /*-------------------------------------------------------------------------
- * H5T_NATIVE_FLOAT
- *-------------------------------------------------------------------------
- */
H5TOOLS_DEBUG("H5T_FLOAT");
- if (type_size == 4) {
- if (type_size != sizeof(float))
- H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not float size");
- nfound += diff_float_element(mem1, mem2, elemtno, opts);
- }
+#ifdef H5_HAVE__FLOAT16
/*-------------------------------------------------------------------------
- * H5T_NATIVE_DOUBLE
+ * H5T_NATIVE_FLOAT16
*-------------------------------------------------------------------------
*/
- else if (type_size == 8) {
- if (type_size != sizeof(double))
- H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not double size");
- nfound += diff_double_element(mem1, mem2, elemtno, opts);
+ if (type_size == H5_SIZEOF__FLOAT16) {
+ if (type_size != sizeof(H5__Float16))
+ H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not _Float16 size");
+ nfound += diff_float16_element(mem1, mem2, elemtno, opts);
}
+ else
+#endif
+ /*-------------------------------------------------------------------------
+ * H5T_NATIVE_FLOAT
+ *-------------------------------------------------------------------------
+ */
+ if (type_size == 4) {
+ if (type_size != sizeof(float))
+ H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not float size");
+ nfound += diff_float_element(mem1, mem2, elemtno, opts);
+ }
+ /*-------------------------------------------------------------------------
+ * H5T_NATIVE_DOUBLE
+ *-------------------------------------------------------------------------
+ */
+ else if (type_size == 8) {
+ if (type_size != sizeof(double))
+ H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not double size");
+ nfound += diff_double_element(mem1, mem2, elemtno, opts);
+ }
#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
- /*-------------------------------------------------------------------------
- * H5T_NATIVE_LDOUBLE
- *-------------------------------------------------------------------------
- */
- else if (type_size == H5_SIZEOF_LONG_DOUBLE) {
- if (type_size != sizeof(long double)) {
- H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not long double size");
- }
- nfound += diff_ldouble_element(mem1, mem2, elemtno, opts);
- } /*H5T_NATIVE_LDOUBLE*/
-#endif /* H5_SIZEOF_LONG_DOUBLE */
+ /*-------------------------------------------------------------------------
+ * H5T_NATIVE_LDOUBLE
+ *-------------------------------------------------------------------------
+ */
+ else if (type_size == H5_SIZEOF_LONG_DOUBLE) {
+ if (type_size != sizeof(long double)) {
+ H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Type size is not long double size");
+ }
+ nfound += diff_ldouble_element(mem1, mem2, elemtno, opts);
+ } /*H5T_NATIVE_LDOUBLE*/
+#endif /* H5_SIZEOF_LONG_DOUBLE */
break; /* H5T_FLOAT class */
@@ -2178,6 +2208,189 @@ diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx,
return nfound;
}
+#ifdef H5_HAVE__FLOAT16
+/*-------------------------------------------------------------------------
+ * Function: diff_float16_element
+ *
+ * Purpose: diff a single H5T_NATIVE_FLOAT16 type
+ *
+ * Return: number of differences found
+ *
+ *-------------------------------------------------------------------------
+ */
+static hsize_t
+diff_float16_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, diff_opt_t *opts)
+{
+ hsize_t nfound = 0; /* number of differences found */
+ H5__Float16 temp1_float16;
+ H5__Float16 temp2_float16;
+ double per;
+ bool both_zero = false;
+ bool isnan1 = false;
+ bool isnan2 = false;
+
+ H5TOOLS_START_DEBUG("delta_bool:%d - percent_bool:%d", opts->delta_bool, opts->percent_bool);
+
+ memcpy(&temp1_float16, mem1, sizeof(H5__Float16));
+ memcpy(&temp2_float16, mem2, sizeof(H5__Float16));
+
+ /* logic for detecting NaNs is different with opts -d, -p and no opts */
+
+ /*-------------------------------------------------------------------------
+ * -d and !-p
+ *-------------------------------------------------------------------------
+ */
+ if (opts->delta_bool && !opts->percent_bool) {
+ /*-------------------------------------------------------------------------
+ * detect NaNs
+ *-------------------------------------------------------------------------
+ */
+ if (opts->do_nans) {
+ isnan1 = isnan(temp1_float16);
+ isnan2 = isnan(temp2_float16);
+ }
+
+ /* both not NaN, do the comparison */
+ if (!isnan1 && !isnan2) {
+ if ((double)ABS(temp1_float16 - temp2_float16) > opts->delta) {
+ opts->print_percentage = 0;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ }
+ /* only one is NaN, assume difference */
+ else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
+ opts->print_percentage = 0;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * !-d and -p
+ *-------------------------------------------------------------------------
+ */
+ else if (!opts->delta_bool && opts->percent_bool) {
+ /*-------------------------------------------------------------------------
+ * detect NaNs
+ *-------------------------------------------------------------------------
+ */
+ if (opts->do_nans) {
+ isnan1 = isnan(temp1_float16);
+ isnan2 = isnan(temp2_float16);
+ }
+ /* both not NaN, do the comparison */
+ if ((!isnan1 && !isnan2)) {
+ PER(temp1_float16, temp2_float16);
+
+ if (not_comparable && !both_zero) {
+ opts->print_percentage = 1;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT_P_NOTCOMP, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ else if (per > opts->percent) {
+ opts->print_percentage = 1;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT_P, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16),
+ (double)ABS(1 - temp2_float16 / temp1_float16));
+ }
+ nfound++;
+ }
+ }
+ /* only one is NaN, assume difference */
+ else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
+ opts->print_percentage = 0;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * -d and -p
+ *-------------------------------------------------------------------------
+ */
+ else if (opts->delta_bool && opts->percent_bool) {
+ /*-------------------------------------------------------------------------
+ * detect NaNs
+ *-------------------------------------------------------------------------
+ */
+ if (opts->do_nans) {
+ isnan1 = isnan(temp1_float16);
+ isnan2 = isnan(temp2_float16);
+ }
+
+ /* both not NaN, do the comparison */
+ if (!isnan1 && !isnan2) {
+ PER(temp1_float16, temp2_float16);
+
+ if (not_comparable && !both_zero) {
+ opts->print_percentage = 1;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT_P_NOTCOMP, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ else if (per > opts->percent && (double)ABS(temp1_float16 - temp2_float16) > opts->delta) {
+ opts->print_percentage = 1;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT_P, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16),
+ (double)ABS(1 - temp2_float16 / temp1_float16));
+ }
+ nfound++;
+ }
+ }
+ /* only one is NaN, assume difference */
+ else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
+ opts->print_percentage = 0;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * no -d and -p
+ *-------------------------------------------------------------------------
+ */
+ else {
+ if (equal_float(temp1_float16, temp2_float16, opts) == false) {
+ opts->print_percentage = 0;
+ print_pos(opts, elem_idx, 0);
+ if (print_data(opts)) {
+ parallel_print(F_FORMAT, (double)temp1_float16, (double)temp2_float16,
+ (double)ABS(temp1_float16 - temp2_float16));
+ }
+ nfound++;
+ }
+ }
+
+ H5TOOLS_ENDDEBUG(": %" PRIuHSIZE " zero:%d", nfound, both_zero);
+ return nfound;
+}
+#endif
+
/*-------------------------------------------------------------------------
* Function: diff_schar_element
*
diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c
index 4641c93..26cde1b 100644
--- a/tools/lib/h5diff_util.c
+++ b/tools/lib/h5diff_util.c
@@ -120,7 +120,11 @@ print_type(hid_t type)
break;
case H5T_FLOAT:
- if (H5Tequal(type, H5T_IEEE_F32BE))
+ if (H5Tequal(type, H5T_IEEE_F16BE))
+ parallel_print("H5T_IEEE_F16BE");
+ else if (H5Tequal(type, H5T_IEEE_F16LE))
+ parallel_print("H5T_IEEE_F16LE");
+ else if (H5Tequal(type, H5T_IEEE_F32BE))
parallel_print("H5T_IEEE_F32BE");
else if (H5Tequal(type, H5T_IEEE_F32LE))
parallel_print("H5T_IEEE_F32LE");
@@ -128,6 +132,10 @@ print_type(hid_t type)
parallel_print("H5T_IEEE_F64BE");
else if (H5Tequal(type, H5T_IEEE_F64LE))
parallel_print("H5T_IEEE_F64LE");
+#ifdef H5_HAVE__FLOAT16
+ else if (H5Tequal(type, H5T_NATIVE_FLOAT16))
+ parallel_print("H5T_NATIVE_FLOAT16");
+#endif
else if (H5Tequal(type, H5T_NATIVE_FLOAT))
parallel_print("H5T_NATIVE_FLOAT");
else if (H5Tequal(type, H5T_NATIVE_DOUBLE))
diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c
index efaddee..5a8c401 100644
--- a/tools/lib/h5tools_dump.c
+++ b/tools/lib/h5tools_dump.c
@@ -2190,7 +2190,11 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_
break;
case H5T_FLOAT:
- if (H5Tequal(type, H5T_IEEE_F32BE) == true)
+ if (H5Tequal(type, H5T_IEEE_F16BE) == true)
+ h5tools_str_append(buffer, "H5T_IEEE_F16BE");
+ else if (H5Tequal(type, H5T_IEEE_F16LE) == true)
+ h5tools_str_append(buffer, "H5T_IEEE_F16LE");
+ else if (H5Tequal(type, H5T_IEEE_F32BE) == true)
h5tools_str_append(buffer, "H5T_IEEE_F32BE");
else if (H5Tequal(type, H5T_IEEE_F32LE) == true)
h5tools_str_append(buffer, "H5T_IEEE_F32LE");
@@ -2202,6 +2206,10 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_
h5tools_str_append(buffer, "H5T_VAX_F32");
else if (H5Tequal(type, H5T_VAX_F64) == true)
h5tools_str_append(buffer, "H5T_VAX_F64");
+#ifdef H5_HAVE__FLOAT16
+ else if (H5Tequal(type, H5T_NATIVE_FLOAT16) == true)
+ h5tools_str_append(buffer, "H5T_NATIVE_FLOAT16");
+#endif
else if (H5Tequal(type, H5T_NATIVE_FLOAT) == true)
h5tools_str_append(buffer, "H5T_NATIVE_FLOAT");
else if (H5Tequal(type, H5T_NATIVE_DOUBLE) == true)
diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c
index 5ef86fb..47893ec 100644
--- a/tools/lib/h5tools_str.c
+++ b/tools/lib/h5tools_str.c
@@ -700,7 +700,17 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai
switch (type_class) {
case H5T_FLOAT:
H5TOOLS_DEBUG("H5T_FLOAT");
- if (sizeof(float) == nsize) {
+#ifdef H5_HAVE__FLOAT16
+ if (sizeof(H5__Float16) == nsize) {
+ /* if (H5Tequal(type, H5T_NATIVE_FLOAT16)) */
+ H5__Float16 tempfloat16;
+
+ memcpy(&tempfloat16, vp, sizeof(H5__Float16));
+ h5tools_str_append(str, OPT(info->fmt_float, "%g"), (double)tempfloat16);
+ }
+ else
+#endif
+ if (sizeof(float) == nsize) {
/* if (H5Tequal(type, H5T_NATIVE_FLOAT)) */
float tempfloat;
diff --git a/tools/lib/h5tools_type.c b/tools/lib/h5tools_type.c
index 7e9f6f7..c5e7472 100644
--- a/tools/lib/h5tools_type.c
+++ b/tools/lib/h5tools_type.c
@@ -55,7 +55,9 @@ h5tools_get_little_endian_type(hid_t tid)
break;
case H5T_FLOAT:
- if (size == 4)
+ if (size == 2)
+ p_type = H5Tcopy(H5T_IEEE_F16LE);
+ else if (size == 4)
p_type = H5Tcopy(H5T_IEEE_F32LE);
else if (size == 8)
p_type = H5Tcopy(H5T_IEEE_F64LE);
@@ -134,7 +136,9 @@ h5tools_get_big_endian_type(hid_t tid)
break;
case H5T_FLOAT:
- if (size == 4)
+ if (size == 2)
+ p_type = H5Tcopy(H5T_IEEE_F16BE);
+ else if (size == 4)
p_type = H5Tcopy(H5T_IEEE_F32BE);
else if (size == 8)
p_type = H5Tcopy(H5T_IEEE_F64BE);