aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Kunze <eric.kunze@arm.com>2024-04-10 15:26:55 -0700
committerEric Kunze <eric.kunze@arm.com>2024-04-18 08:15:08 -0700
commit0e121c064e051716bdfca892b210fa52c792ac29 (patch)
treefe9b31770921ebadd735b7443d9537ca90ce7379
parent9d14082fe5176ec91d006d89ccdb2d62f6ca839f (diff)
downloadspecification-0e121c064e051716bdfca892b210fa52c792ac29.tar.gz
Clarify error bound for non-normal values
Signed-off-by: Eric Kunze <eric.kunze@arm.com> Change-Id: I9678952cc78cdf90272ccd5179b6220c293d62f7
-rw-r--r--chapters/introduction.adoc12
-rw-r--r--pseudocode/library/generic_helpers.tosac6
-rw-r--r--pseudocode/library/numeric_accuracy_helpers.tosac14
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.
| <<EXP>>
| 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<in_out_t>) * (1+abs(x))` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(out_ref, (1+abs(x)), 0, 1)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<POW>>
@@ -288,19 +288,19 @@ Then `tosa_reference_check_fp_bnd<in_out_t>(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<in_out_t>) * (2 * (1+abs(log(abs(x))*y)))` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(out_ref, 2 * (1+abs(log(abs(x))*y)), 0, 1)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<SIGMOID>>
| 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<in_out_t>) * (2 * (1+abs(x)))` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(out_ref, 2 * (1+abs(x)), 0, 1)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<TANH>>
| 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<in_out_t>) * max(0.5, abs(out_ref) * (4 * (1+abs(x))))` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(out_ref, 4 * (1+abs(x)), 0.5, 1)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<REDUCE_SUM>>
@@ -321,13 +321,13 @@ Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be
| <<COS>>
| 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<in_out_t>/2)` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(x, 1+abs(x), 0, 2)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<SIN>>
| 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<in_out_t>/2)` +
+Let `err_bnd = calcAbsErrorBound<in_out_t>(x, abs(x), 0, 2)` +
Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<RESIZE>>
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<in_out_t>();
// 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<in_out_t>();
+
+// 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<in_t> () {
case fp8e5m2_t: return 2;
}
}
+
+double calcAbsErrorBound<in_t>(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<in_t> / normal_divisor) * value_bound;
+ }
+ return error_bound;
+} \ No newline at end of file