aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Kunze <eric.kunze@arm.com>2024-01-22 16:54:29 -0800
committerEric Kunze <eric.kunze@arm.com>2024-01-25 13:19:44 -0800
commit608588390a90e6e337a592b62cf811d1ea8ea0fd (patch)
treece73d71540cf6e58fb94b6a12b90d5c8c04cdd4c
parent0808d63e4db076fbbd02e806272ae4ccae6ed72c (diff)
downloadspecification-608588390a90e6e337a592b62cf811d1ea8ea0fd.tar.gz
Handle CAST from fp-type to narrow integer types
Be explicit that the value is converted to int32 and then clamped to the output type range. Also remove use of apply_clip, replacing with either apply_clip_s or apply_clip_u Signed-off-by: Eric Kunze <eric.kunze@arm.com> Change-Id: I0efc7f4d653c1bef13c9989cfe2647208dad9617
-rw-r--r--chapters/introduction.adoc2
-rw-r--r--chapters/pseudocode.adoc15
-rw-r--r--pseudocode/operators/CAST.tosac4
-rw-r--r--pseudocode/operators/CLAMP.tosac2
-rw-r--r--pseudocode/operators/RESCALE.tosac4
5 files changed, 21 insertions, 6 deletions
diff --git a/chapters/introduction.adoc b/chapters/introduction.adoc
index 8b5be21..ae5c7b1 100644
--- a/chapters/introduction.adoc
+++ b/chapters/introduction.adoc
@@ -739,7 +739,7 @@ void generate_lookup_table(int16_t *table, int32_t (*reference)(int32_t))
{
for (int i = -256; i <= 256; i++) {
int32_t value = (*reference)(i);
- table[i + 256] = static_cast<int16_t>(apply_clip<int32_t>(value, -32768, +32767));
+ table[i + 256] = static_cast<int16_t>(apply_clip_s<int32_t>(value, -32768, +32767));
}
}
----
diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
index 0de7f39..9e3b7bd 100644
--- a/chapters/pseudocode.adoc
+++ b/chapters/pseudocode.adoc
@@ -262,6 +262,13 @@ in_t apply_clip_s<in_t>(in_t value, in_t min_val, in_t max_val) {
return value;
}
+in_t apply_clip_u<in_t>(in_t value, in_t min_val, in_t max_val) {
+ REQUIRE(zero_extend<int64_t>(min_val) <= zero_extend<int64_t>(max_val));
+ value = apply_max_u<in_t>(value, min_val);
+ value = apply_min_u<in_t>(value, max_val);
+ return value;
+}
+
in_t apply_exp<in_t>(in_t input) {
return e to the power input
}
@@ -296,6 +303,10 @@ in_t apply_max_s<in_t>(in_t a, in_t b) {
if (sign_extend<int64_t>(a) >= sign_extend<int64_t>(b)) return a; else return b;
}
+in_t apply_max_u<in_t>(in_t a, in_t b) {
+ if (zero_extend<uint64_t>(a) >= zero_extend<int64_t>(b)) return a; else return b;
+}
+
in_t apply_min_s<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) {
if (isNaN(a) || isNaN(b)) {
@@ -307,6 +318,10 @@ in_t apply_min_s<in_t>(in_t a, in_t b) {
if (sign_extend<int64_t>(a) < sign_extend<int64_t>(b)) return a; else return b;
}
+in_t apply_min_u<in_t>(in_t a, in_t b) {
+ if (zero_extend<int64_t>(a) < zero_extend<int64_t>(b)) return a; else return b;
+}
+
in_t apply_mul_s<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) return a * b;
int64_t c = sign_extend<int64_t>(a) * sign_extend<int64_t>(b);
diff --git a/pseudocode/operators/CAST.tosac b/pseudocode/operators/CAST.tosac
index 8d816ca..fac73e3 100644
--- a/pseudocode/operators/CAST.tosac
+++ b/pseudocode/operators/CAST.tosac
@@ -17,11 +17,11 @@ for_each(index in shape) {
} else if (out_t == fp16_t || out_t == bf16_t || out_t == fp32_t) {
out = round_to_nearest_float(in);
} else if (in_t == fp16_t || in_t == bf16_t || in_t == fp32_t) {
- out = apply_clip<out_t>(round_to_nearest_int(in), minimum<out_t>, maximum<out_t>);
+ out = truncate<out_t>(apply_clip_s<i32_t>(round_to_nearest_int(in), minimum<out_t>, maximum<out_t>));
} else if (sizeof(out_t) >= sizeof(in_t)) {
out = sign_extend<out_t>(in);
} else {
- out = truncate(in);
+ out = truncate<out_t>(in);
}
tensor_write<out_t>(output, shape, index, out);
}
diff --git a/pseudocode/operators/CLAMP.tosac b/pseudocode/operators/CLAMP.tosac
index 7a26d50..cfac632 100644
--- a/pseudocode/operators/CLAMP.tosac
+++ b/pseudocode/operators/CLAMP.tosac
@@ -10,6 +10,6 @@
ERROR_IF(max_val < min_val);
for_each(index in shape) {
in_out_t value = tensor_read<in_out_t>(input, shape, index);
- value = apply_clip<in_out_t>(value, min_val, max_val);
+ value = apply_clip_s<in_out_t>(value, min_val, max_val);
tensor_write<in_out_t>(output, shape, index, value);
}
diff --git a/pseudocode/operators/RESCALE.tosac b/pseudocode/operators/RESCALE.tosac
index c29bddd..3ebb8d6 100644
--- a/pseudocode/operators/RESCALE.tosac
+++ b/pseudocode/operators/RESCALE.tosac
@@ -43,14 +43,14 @@ for_each(index in shape) {
if (output_unsigned) {
int32_t extended_out_zp = zero_extend<int32_t>(output_zp);
result = apply_add_s<int32_t>(result, extended_out_zp);
- out_t out = static_cast<out_t>(apply_clip<int32_t>(result,
+ out_t out = static_cast<out_t>(apply_clip_u<i32_t>(result,
minimum_u<out_t>,
maximum_u<out_t>));
}
else {
int32_t extended_out_zp = sign_extend<int32_t>(output_zp);
result = apply_add_s<int32_t>(result, extended_out_zp);
- out_t out = static_cast<out_t>(apply_clip<int32_t>(result,
+ out_t out = static_cast<out_t>(apply_clip_s<i32_t>(result,
minimum_s<out_t>,
maximum_s<out_t>));
}