diff options
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/h5diff_array.c | 265 | ||||
-rw-r--r-- | tools/lib/h5diff_util.c | 10 | ||||
-rw-r--r-- | tools/lib/h5tools_dump.c | 10 | ||||
-rw-r--r-- | tools/lib/h5tools_str.c | 12 | ||||
-rw-r--r-- | tools/lib/h5tools_type.c | 8 |
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); |