aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominic Symes <dominic.symes@arm.com>2023-11-07 11:46:16 +0000
committerDominic Symes <dominic.symes@arm.com>2023-11-22 17:21:14 +0000
commita46cf1d2f3b22b1d54f71ddb3a99aa16f9e75a94 (patch)
treeb94da5999509ff9c26f2246963d3c83f5c4b3a01
parentf43fdce7f8984cbec1c4aa28b2199a1c99943ece (diff)
downloadspecification-a46cf1d2f3b22b1d54f71ddb3a99aa16f9e75a94.tar.gz
Main Conformance: Update RSQRT precision
Change RSQRT precision to 2 ulp to allow unfused square root and reciprocal. Also fixes: - a typo in EXP and POW conformance - exp2() handling of large negative values - symmetry about 0 of test set S=4 data generation - err_bnd cannot be negative - ulp not taken for reference value of 0 Change-Id: Idaeeb7b615f1634e8e09dea5f82827039780b462 Signed-off-by: Dominic Symes <dominic.symes@arm.com>
-rw-r--r--chapters/appendix_a.adoc4
-rw-r--r--chapters/introduction.adoc10
-rw-r--r--chapters/pseudocode.adoc8
3 files changed, 13 insertions, 9 deletions
diff --git a/chapters/appendix_a.adoc b/chapters/appendix_a.adoc
index 17007b5..b162738 100644
--- a/chapters/appendix_a.adoc
+++ b/chapters/appendix_a.adoc
@@ -114,8 +114,8 @@ The aim of this test set is to check a mixture of zero and non-zero products.
[cols="1,9"]
|===
| p | tosa_mi_data(S, KS, p, k, i) =
-| 0 | (k==KS/2) ? +0.5 : (set_data(2*S, i) < 0 ? 0.0 : (B/sqrt(KS))*set_data(2*S+1, i))
-| 1 | (k==KS/2) ? -0.5 : (set_data(2*S, i) < 0 ? (B/sqrt(KS))*set_data(2*S+1, i) : 0.0)
+| 0 | (k==KS/2) ? (set_data(2*S, i) < 0 ? -0.5 : +0.5) : (set_data(2*S, i) < 0 ? 0.0 : (B/sqrt(KS))*set_data(2*S+1, i))
+| 1 | (k==KS/2) ? (set_data(2*S, i) < 0 ? +0.5 : -0.5) : (set_data(2*S, i) < 0 ? (B/sqrt(KS))*set_data(2*S+1, i) : 0.0)
| 2 | 0.0
|===
diff --git a/chapters/introduction.adoc b/chapters/introduction.adoc
index 1fabcc3..4b0696c 100644
--- a/chapters/introduction.adoc
+++ b/chapters/introduction.adoc
@@ -259,7 +259,7 @@ Otherwise:the result must be within 1 ulp of the mathematical result.
| <<RSQRT>>
| If the input is less than zero the result must be a NaN. +
Otherwise if the input is a zero the output must be an infinity of the same sign. +
-Otherwise the result must be within 1 ulp of the mathematical result.
+Otherwise the result must be within 2 ulp of the mathematical result.
| <<SIGMOID>>, <<TANH>>, <<LOG>>, <<ERF>>
| If the input to LOG is less than zero then the result must be a NaN. +
@@ -270,14 +270,14 @@ 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 = out_ref*exp2(-normal_fraction<in_out_t>)*(1+abs(x))` +
-Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, out_bnd)` must be true
+Let `err_bnd = abs(out_ref) * exp2(-normal_frac<in_out_t>) * (1+abs(x))` +
+Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<POW>>
| Let `x`, `y` be input elements and `out_imp` the implementation output of `pow(x,y)`. +
Let `out_ref` be the result of the fp64_t reference implementation of `pow(x,y)`. +
-Let `err_bnd = out_ref*exp2(-normal_fraction<in_out_t>)*(1+abs(log(abs(x))*y))` +
-Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, out_bnd)` must be true
+Let `err_bnd = abs(out_ref) * exp2(-normal_frac<in_out_t>) * (1+abs(log(abs(x))*y))` +
+Then `tosa_reference_check_fp_bnd<in_out_t>(out_imp, out_ref, err_bnd)` must be true
| <<REDUCE_SUM>>
| Each output can be expressed as a dot product of an input vector with a vector of ones. +
diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
index 0a8f598..0de7f39 100644
--- a/chapters/pseudocode.adoc
+++ b/chapters/pseudocode.adoc
@@ -422,7 +422,10 @@ The functions below return the ranges according to type.
[source,c++]
----
fp64_t exp2(int n) {
- REQUIRE(-1022 <= n && n <= 1023);
+ if (n < -1075) {
+ return 0.0; // smaller than smallest denormal
+ }
+ REQUIRE(n <= 1023);
fp64_t v = 1.0;
while (n > 0) { v = v*2.0; n--; }
while (n < 0) { v = v/2.0; n++; }
@@ -472,7 +475,7 @@ For the second function, the permitted error range is specified as an absolute e
----
bool tosa_reference_check_fp<in_t>(in_t test_value, fp64_t ref_value, fp64_t num_ulp) {
fp64_t err_bnd = 0.0;
- if (is_normal_fp64(ref_value)) {
+ if (is_normal_fp64(ref_value) && abs(ref_value) != 0) {
int ref_exp = ilog2(abs(ref_value));
fp64_t ref_pow2 = max(exp2(ref_exp), normal_min<in_t>);
fp64_t val_ulp = ref_pow2 * exp2(-normal_frac<in_t>);
@@ -485,6 +488,7 @@ bool tosa_reference_check_fp_bnd<in_t>(in_t test_value, fp64_t ref_value, fp64_t
if (is_a_NaN(ref_value)) {
return is_a_NaN(test_value);
}
+ REQUIRE(err_bnd >= 0.0);
if (ref_value < 0) {
ref_value = -ref_value;
test_value = -test_value;