From 0e121c064e051716bdfca892b210fa52c792ac29 Mon Sep 17 00:00:00 2001 From: Eric Kunze Date: Wed, 10 Apr 2024 15:26:55 -0700 Subject: Clarify error bound for non-normal values Signed-off-by: Eric Kunze Change-Id: I9678952cc78cdf90272ccd5179b6220c293d62f7 --- chapters/introduction.adoc | 12 ++++++------ pseudocode/library/generic_helpers.tosac | 6 ++++++ pseudocode/library/numeric_accuracy_helpers.tosac | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/chapters/introduction.adoc b/chapters/introduction.adoc index 0030757..5406129 100644 --- a/chapters/introduction.adoc +++ b/chapters/introduction.adoc @@ -280,7 +280,7 @@ Otherwise the result must be within 5 ulp of the mathematical result. | <> | Let `x` be an input element and `out_imp` the implementation output of `exp(x)`. + Let `out_ref` be the result of the fp64_t reference implementation of `exp(x)`. + -Let `err_bnd = abs(out_ref) * exp2(-normal_frac) * (1+abs(x))` + +Let `err_bnd = calcAbsErrorBound(out_ref, (1+abs(x)), 0, 1)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> @@ -288,19 +288,19 @@ Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be Let `out_imp` be the implementation output of `pow(x,y)`. + If `x` is less than zero and `y` is non-integral then the result must be a NaN. + Let `out_ref` be the result of the fp64_t reference implementation of `pow(x,y)`. + -Let `err_bnd = abs(out_ref) * exp2(-normal_frac) * (2 * (1+abs(log(abs(x))*y)))` + +Let `err_bnd = calcAbsErrorBound(out_ref, 2 * (1+abs(log(abs(x))*y)), 0, 1)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> | Let `x` be an input element and `out_imp` the implementation output. + Let `out_ref` be the result of the fp64_t reference implementation. + -Let `err_bnd = abs(out_ref) * exp2(-normal_frac) * (2 * (1+abs(x)))` + +Let `err_bnd = calcAbsErrorBound(out_ref, 2 * (1+abs(x)), 0, 1)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> | Let `x` be an input element and `out_imp` the implementation output. + Let `out_ref` be the result of the fp64_t reference implementation. + -Let `err_bnd = exp2(-normal_frac) * max(0.5, abs(out_ref) * (4 * (1+abs(x))))` + +Let `err_bnd = calcAbsErrorBound(out_ref, 4 * (1+abs(x)), 0.5, 1)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> @@ -321,13 +321,13 @@ Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be | <> | Let `x` be an input element and `out_imp` the implementation output of `cos(x)`. + Let `out_ref` be the result of the fp64_t reference implementation of `cos(x)`. + -Let `err_bnd = abs(x) * exp2(-normal_frac/2)` + +Let `err_bnd = calcAbsErrorBound(x, 1+abs(x), 0, 2)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> | Let `x` be an input element and `out_imp` the implementation output of `sin(x)`. + Let `out_ref` be the result of the fp64_t reference implementation of `sin(x)`. + -Let `err_bnd = abs(x) * exp2(-normal_frac/2)` + +Let `err_bnd = calcAbsErrorBound(x, abs(x), 0, 2)` + Then `tosa_reference_check_fp_bnd(out_imp, out_ref, err_bnd)` must be true | <> diff --git a/pseudocode/library/generic_helpers.tosac b/pseudocode/library/generic_helpers.tosac index 6dc2755..cffd55c 100644 --- a/pseudocode/library/generic_helpers.tosac +++ b/pseudocode/library/generic_helpers.tosac @@ -69,3 +69,9 @@ in_out_t maximum_u(); // return the minimum value when interpreting type in_out_t as an unsigned value as returned by the make_unsigned helper. in_out_t minimum_u(); + +// return true if the given value is a NaN. Only valid for floating-point types +bool is_a_NaN(fp64_t value); + +// return true if value is a normal fp64 value (Not zero, subnormal, infinite or NaN) +bool is_normal_fp64(fp64_t value); \ No newline at end of file diff --git a/pseudocode/library/numeric_accuracy_helpers.tosac b/pseudocode/library/numeric_accuracy_helpers.tosac index b89d898..dbff2dd 100644 --- a/pseudocode/library/numeric_accuracy_helpers.tosac +++ b/pseudocode/library/numeric_accuracy_helpers.tosac @@ -56,3 +56,17 @@ int normal_frac () { case fp8e5m2_t: return 2; } } + +double calcAbsErrorBound(double bound_magnitude, double bounds_value, + double lower_bound, double normal_divisor) { + double error_bound = 0.0; + // Avoid cases where we generate an error_bound of NaN by multiplying inf * 0 + if (is_finite(bounds_value) || abs(bound_magnitude) != 0.0) { + double value_bound = abs(bound_magnitude) * bounds_value; + if (lower_bound > 0) { + value_bound = max(lower_bound, value_bound); + } + error_bound = exp2(-normal_frac / normal_divisor) * value_bound; + } + return error_bound; +} \ No newline at end of file -- cgit v1.2.1