blob: 7bca697c9206248408f9dca7303e6e5cc8b1af6d [file] [log] [blame]
Eric Kunzee5e26762020-10-13 16:11:07 -07001
Jerry Ged6a04612023-12-15 22:45:39 +00002// Copyright (c) 2020-2024, ARM Limited.
Eric Kunzee5e26762020-10-13 16:11:07 -07003//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#include "type_conversion.h"
James Ward736fd1a2023-01-23 17:13:37 +000017#include "arith_util.h"
Won Jeon2c34b462024-02-06 18:37:00 +000018#include "float_utils.h"
Jerry Ge9c9c8da2023-07-19 23:08:16 +000019#include "half.hpp"
20#include "quant_util.h"
Eric Kunzee5e26762020-10-13 16:11:07 -070021#include "template_types.h"
22#include <cmath>
23
24using namespace TosaReference;
25using namespace Eigen;
26using namespace tosa;
27
Won Jeon2c34b462024-02-06 18:37:00 +000028using fp16 = tosa::reference::internal::float_t<int16_t, 5, true, true, true>;
29using bf16 = tosa::reference::internal::float_t<int16_t, 8, true, true, true>;
30using fp32 = tosa::reference::internal::float_t<int32_t, 8, true, true, true>;
31using fp8e4m3 = tosa::reference::internal::float_t<int8_t, 4, true, true, false>;
32using fp8e5m2 = tosa::reference::internal::float_t<int8_t, 5, true, true, true>;
33
Tai Lya4d748b2023-03-28 22:06:56 +000034template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Jerry Ge9c9c8da2023-07-19 23:08:16 +000035OpRescale<Rank, InDtype, OutDtype>::OpRescale(SubgraphTraverser* sgt_, TosaAttributeBase* attribute_, uint64_t id_)
Kevin Chengacb550f2021-06-29 15:32:19 -070036 : GraphNode(sgt_, Op_RESCALE, id_)
Eric Kunzee5e26762020-10-13 16:11:07 -070037{
Tai Ly6e1e2bc2024-03-01 20:59:32 +000038 setRequiredOperands(3, 1);
Eric Kunzee5e26762020-10-13 16:11:07 -070039 INIT_ATTRIBUTE(Rescale);
TatWai Chong0dac6c92024-04-02 15:45:29 -070040
41 QMax_s = getSignedMaximum<OutDtype>();
42 QMin_s = getSignedMinimum<OutDtype>();
43 QMax_u = getUnsignedMaximum<OutDtype>();
44 QMin_u = getUnsignedMinimum<OutDtype>();
Eric Kunzee5e26762020-10-13 16:11:07 -070045}
46
Tai Lya4d748b2023-03-28 22:06:56 +000047template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -070048OpRescale<Rank, InDtype, OutDtype>::~OpRescale()
49{
50 if (attribute)
51 delete attribute;
52}
53
Tai Lya4d748b2023-03-28 22:06:56 +000054template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -070055int OpRescale<Rank, InDtype, OutDtype>::checkTensorAttributes()
56{
Jerry Gea793f462023-04-11 00:05:02 +000057 // Check Tosa Level
58 auto tosa_level = g_func_config.tosa_level;
59 LEVEL_CHECK(Rank <= tosa_level.MAX_RANK, "Rank should be smaller than or equal to MAX_RANK");
60
Eric Kunzee5e26762020-10-13 16:11:07 -070061 if (validateRequiredOperands())
62 return 1;
63
Eric Kunzee5e26762020-10-13 16:11:07 -070064 // output and input must be the same rank and size
65 if (inputs[0]->matchRankSize(*outputs[0]))
66 {
67 printNodeValidationError("OpRescale: input and output rank/size must match");
68 return 1;
69 }
70
71 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
72 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
73
74 ASSERT_MEM(in && out);
75
Tai Ly6e1e2bc2024-03-01 20:59:32 +000076 multiplierI32 = dynamic_cast<TosaReference::TensorTemplate<TMultiplierI32>*>(inputs[1]);
77 multiplierI16 = dynamic_cast<TosaReference::TensorTemplate<TMultiplierI16>*>(inputs[1]);
78 shift = dynamic_cast<TosaReference::TensorTemplate<TShift>*>(inputs[2]);
79 ASSERT_MEM(shift);
80
81 if (attribute->scale32())
82 {
83 ASSERT_MEM(multiplierI32);
84 }
85 else
86 {
87 ASSERT_MEM(multiplierI16);
88 }
89
Eric Kunze9c0a5072024-03-19 21:14:07 +000090 auto input_zp = attribute->input_zp();
91 auto output_zp = attribute->output_zp();
92 auto input_unsigned = attribute->input_unsigned();
93 auto output_unsigned = attribute->output_unsigned();
94
95 // Note that how rescale op interprets signedness of the tensor depends on
96 // the value of input_unsigned and output_unsigned attributes, and doesn't
97 // care about the type of tensor itself.
98
99 if (!isI8(InDtype) && (!isI16(InDtype) || input_unsigned == false) && (input_zp != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -0700100 {
Tai Lya4d748b2023-03-28 22:06:56 +0000101 printNodeValidationError("OpRescale: Input TOSA_REF_TYPE not INT8/UINT8/UINT16 and zero point not 0");
Kevin Chengcc61be32021-10-14 17:09:57 -0700102 return 1;
103 }
104
Eric Kunze9c0a5072024-03-19 21:14:07 +0000105 if (!isI8(OutDtype) && (!isI16(OutDtype) || output_unsigned == false) && (output_zp != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -0700106 {
Tai Lya4d748b2023-03-28 22:06:56 +0000107 printNodeValidationError("OpRescale: Output TOSA_REF_TYPE not INT8/UINT8/UINT16 and zero point not 0");
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100108 return 1;
109 }
110
Eric Kunze9c0a5072024-03-19 21:14:07 +0000111 if (isI16(InDtype) && (input_unsigned == true) && (input_zp != 0) && (input_zp != 32768))
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100112 {
Eric Kunze9c0a5072024-03-19 21:14:07 +0000113 printNodeValidationError("OpRescale: Input unsigned int16 and zero point not 0 or 32768");
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100114 return 1;
115 }
116
Eric Kunze9c0a5072024-03-19 21:14:07 +0000117 if (isI16(OutDtype) && (output_unsigned == true) && (output_zp != 0) && (output_zp != 32768))
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100118 {
Eric Kunze9c0a5072024-03-19 21:14:07 +0000119 printNodeValidationError("OpRescale: Output unsigned int16 and zero point not 0 or 32768");
Kevin Chengcc61be32021-10-14 17:09:57 -0700120 return 1;
121 }
122
Tai Lya4d748b2023-03-28 22:06:56 +0000123 if (attribute->scale32() && (InDtype == TOSA_REF_TYPE_INT48))
Kevin Chengcc61be32021-10-14 17:09:57 -0700124 {
125 printNodeValidationError("OpRescale: Scale set to true but input type is INT48");
126 return 1;
127 }
128
129 if ((!attribute->scale32()) && attribute->double_round())
130 {
131 printNodeValidationError("OpRescale: Scale set to false but double round set to true");
132 return 1;
133 }
134
Eric Kunzee5e26762020-10-13 16:11:07 -0700135 return 0;
136}
137
Eric Kunzea8098c02023-09-07 00:31:54 +0000138// helpers to convert types
139static int64_t zero_extend(int8_t val)
140{
141 uint8_t* rval = reinterpret_cast<uint8_t*>(&val);
142 return static_cast<int64_t>(*rval);
143}
144static int64_t zero_extend(int16_t val)
145{
146 uint16_t* rval = reinterpret_cast<uint16_t*>(&val);
147 return static_cast<int64_t>(*rval);
148}
149
Tai Lya4d748b2023-03-28 22:06:56 +0000150template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700151int OpRescale<Rank, InDtype, OutDtype>::eval()
152{
Tai Ly6e1e2bc2024-03-01 20:59:32 +0000153 int32_t input_zp = attribute->input_zp();
154 int32_t output_zp = attribute->output_zp();
155 std::vector<int32_t> multiplier;
156 std::vector<int32_t> shift;
157 bool scale32 = attribute->scale32();
158 bool double_round = attribute->double_round();
159 bool per_channel = attribute->per_channel();
160 bool input_unsigned = attribute->input_unsigned();
161 bool output_unsigned = attribute->output_unsigned();
Eric Kunzee5e26762020-10-13 16:11:07 -0700162
Eric Kunzee5e26762020-10-13 16:11:07 -0700163 // reshape [d0, d1, ..., dn] into [d0 * d1 ..., dn]
164 Eigen::array<Eigen::Index, 2> shape_2d;
165 shape_2d[0] = 1;
166 if (Rank > 0)
167 {
168 for (int i = 0; i < Rank - 1; i++)
169 {
170 shape_2d[0] *= this->in->getShape()[i];
171 }
172 shape_2d[1] = this->in->getShape()[Rank - 1];
173 }
174 else
175 {
176 shape_2d[1] = 1;
177 }
178 ETensor2<InEigenType> input_reshaped = this->in->getTensor().reshape(shape_2d);
179
180 ETensor2<OutEigenType> output_2d(shape_2d);
181
Tai Ly6e1e2bc2024-03-01 20:59:32 +0000182 if (scale32)
183 {
184 auto multiplier_val = this->multiplierI32->getTensor();
185 for (int i = 0; i < multiplier_val.size(); i++)
186 {
187 multiplier.push_back(static_cast<int32_t>(multiplier_val(i)));
188 }
189 }
190 else
191 {
192 auto multiplier_val = this->multiplierI16->getTensor();
193 for (int i = 0; i < multiplier_val.size(); i++)
194 {
195 multiplier.push_back(static_cast<int32_t>(multiplier_val(i)));
196 }
197 }
198 auto shift_val = this->shift->getTensor();
199 for (int i = 0; i < shift_val.size(); i++)
200 {
201 shift.push_back(static_cast<int32_t>(shift_val(i)));
202 }
203
Eric Kunzee5e26762020-10-13 16:11:07 -0700204 if (per_channel)
205 {
206 ETensor2<InEigenType> curr_channel_slice_prescaled;
207 ETensor2<OutEigenType> curr_channel_slice_postscaled;
208 int32_t channel_multiplier, channel_shift;
209 Eigen::array<Eigen::Index, 2> begin, size;
210 size = Eigen::array<Eigen::Index, 2>({ shape_2d[0], 1 });
Kevin Chengacb550f2021-06-29 15:32:19 -0700211 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700212 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700213 for (int32_t i = 0; i < shape_2d[1]; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700214 {
TatWai Chong08fe7a52024-03-21 14:34:33 -0700215 begin = Eigen::array<Eigen::Index, 2>({ 0, i });
216 curr_channel_slice_prescaled = input_reshaped.slice(begin, size);
217 channel_multiplier = multiplier[i];
218 channel_shift = shift[i];
219 curr_channel_slice_postscaled =
220 curr_channel_slice_prescaled.unaryExpr([=](InEigenType in_val) -> OutEigenType {
Eric Kunzea8098c02023-09-07 00:31:54 +0000221 int64_t input_zp_shifted;
222 if (input_unsigned)
223 {
224 int64_t in_val64;
225 int64_t in_zp64;
226 switch (GetNumBits<InDtype>::value)
227 {
228 case 8:
229 in_val64 = zero_extend(static_cast<int8_t>(in_val));
230 in_zp64 = zero_extend(static_cast<int8_t>(input_zp));
231 break;
232 case 16:
233 in_val64 = zero_extend(static_cast<int16_t>(in_val));
234 in_zp64 = zero_extend(static_cast<int16_t>(input_zp));
235 break;
236 default:
237 in_val64 = static_cast<int64_t>(in_val);
238 in_zp64 = static_cast<int64_t>(input_zp);
239 break;
240 }
241 input_zp_shifted = in_val64 - in_zp64;
242 }
243 else
244 {
245 input_zp_shifted = in_val - input_zp;
246 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700247 int32_t scaled;
248 if (scale32)
Eric Kunzea8098c02023-09-07 00:31:54 +0000249 scaled = TosaReference::QuantUtil::apply_scale_32(static_cast<int32_t>(input_zp_shifted),
250 channel_multiplier, channel_shift,
251 double_round);
Kevin Chengacb550f2021-06-29 15:32:19 -0700252 else
253 scaled = TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, channel_multiplier,
254 channel_shift);
Eric Kunzea8098c02023-09-07 00:31:54 +0000255 int64_t output_zp_extended;
256 if (output_unsigned)
257 {
258 switch (GetNumBits<OutDtype>::value)
259 {
260 case 8:
261 output_zp_extended = zero_extend(static_cast<int8_t>(output_zp));
262 break;
263 case 16:
264 output_zp_extended = zero_extend(static_cast<int16_t>(output_zp));
265 break;
266 default:
267 output_zp_extended = static_cast<int64_t>(output_zp);
268 break;
269 }
270 }
271 else
272 {
273 output_zp_extended = static_cast<int64_t>(output_zp);
274 }
TatWai Chong0dac6c92024-04-02 15:45:29 -0700275
Eric Kunzea8098c02023-09-07 00:31:54 +0000276 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp_extended;
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000277 int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
278 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
TatWai Chong0dac6c92024-04-02 15:45:29 -0700279
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000280 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
281 {
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000282 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" +
283 std::to_string(output_zp) + "] not in i32 range";
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000284 throw desc;
285 }
TatWai Chong0dac6c92024-04-02 15:45:29 -0700286
287 // Treat the output values as unsigned if `output_unsigned` is true.
288 int32_t clipped_val = (output_unsigned)
289 ? applyClip<int32_t, uint32_t>(res_in_64, QMin_u, QMax_u)
290 : applyClip<int32_t, int32_t>(res_in_64, QMin_s, QMax_s);
291
292 OutEigenType out_val = static_cast<OutEigenType>(clipped_val);
Kevin Chengacb550f2021-06-29 15:32:19 -0700293 return out_val;
294 });
295
296 for (int32_t j = 0; j < shape_2d[0]; j++)
297 {
298 output_2d(j, i) = curr_channel_slice_postscaled(j, 0);
299 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700300 }
301 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700302 catch (std::string desc)
303 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000304 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700305 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700306 }
307 else
308 {
309 int32_t tensor_multiplier = multiplier[0];
310 int32_t tensor_shift = shift[0];
Kevin Chengacb550f2021-06-29 15:32:19 -0700311 try
312 {
TatWai Chong08fe7a52024-03-21 14:34:33 -0700313 output_2d = input_reshaped.unaryExpr([=](InEigenType in_val) -> OutEigenType {
314 int64_t input_zp_shifted;
315 if (input_unsigned)
316 {
317 int64_t in_val64;
318 int64_t in_zp64;
319 switch (GetNumBits<InDtype>::value)
Eric Kunzea8098c02023-09-07 00:31:54 +0000320 {
TatWai Chong08fe7a52024-03-21 14:34:33 -0700321 case 8:
322 in_val64 = zero_extend(static_cast<int8_t>(in_val));
323 in_zp64 = zero_extend(static_cast<int8_t>(input_zp));
324 break;
325 case 16:
326 in_val64 = zero_extend(static_cast<int16_t>(in_val));
327 in_zp64 = zero_extend(static_cast<int16_t>(input_zp));
328 break;
329 default:
330 in_val64 = static_cast<int64_t>(in_val);
331 in_zp64 = static_cast<int64_t>(input_zp);
332 break;
Eric Kunzea8098c02023-09-07 00:31:54 +0000333 }
TatWai Chong08fe7a52024-03-21 14:34:33 -0700334 input_zp_shifted = in_val64 - in_zp64;
335 }
336 else
337 {
338 input_zp_shifted = in_val - input_zp;
339 }
340 int32_t scaled;
341 if (scale32)
342 scaled = TosaReference::QuantUtil::apply_scale_32(input_zp_shifted, tensor_multiplier, tensor_shift,
343 double_round);
344 else
345 scaled =
346 TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, tensor_multiplier, tensor_shift);
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000347
TatWai Chong08fe7a52024-03-21 14:34:33 -0700348 int64_t output_zp_extended;
349 if (output_unsigned)
350 {
351 switch (GetNumBits<OutDtype>::value)
Eric Kunzea8098c02023-09-07 00:31:54 +0000352 {
TatWai Chong08fe7a52024-03-21 14:34:33 -0700353 case 8:
354 output_zp_extended = zero_extend(static_cast<int8_t>(output_zp));
355 break;
356 case 16:
357 output_zp_extended = zero_extend(static_cast<int16_t>(output_zp));
358 break;
359 default:
360 output_zp_extended = static_cast<int64_t>(output_zp);
361 break;
Eric Kunzea8098c02023-09-07 00:31:54 +0000362 }
TatWai Chong08fe7a52024-03-21 14:34:33 -0700363 }
364 else
365 {
366 output_zp_extended = static_cast<int64_t>(output_zp);
367 }
368 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp_extended;
369 int64_t i32_max_in_64 = IsSignedInt<OutDtype>()
370 ? static_cast<int64_t>(std::numeric_limits<int32_t>::max())
371 : static_cast<int64_t>(std::numeric_limits<uint32_t>::max());
372 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
Eric Kunzea8098c02023-09-07 00:31:54 +0000373
TatWai Chong08fe7a52024-03-21 14:34:33 -0700374 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
375 {
376 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" +
377 std::to_string(output_zp) + "] not in i32 range";
378 throw desc;
379 }
380
TatWai Chong0dac6c92024-04-02 15:45:29 -0700381 // Treat the output values as unsigned if `output_unsigned` is true.
382 int32_t clipped_val = (output_unsigned) ? applyClip<int32_t, uint32_t>(res_in_64, QMin_u, QMax_u)
383 : applyClip<int32_t, int32_t>(res_in_64, QMin_s, QMax_s);
384
385 OutEigenType out_val = static_cast<OutEigenType>(clipped_val);
TatWai Chong08fe7a52024-03-21 14:34:33 -0700386 return out_val;
387 });
Kevin Chengacb550f2021-06-29 15:32:19 -0700388 }
389 catch (std::string desc)
390 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000391 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700392 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700393 }
394
395 // reshape [d0 * d1 ..., dn] back to [d0, d1, ..., dn]
396 Eigen::array<Eigen::Index, Rank> output_shape;
397 for (int i = 0; i < Rank; i++)
398 {
399 output_shape[i] = this->out->getShape()[i];
400 }
401 this->out->getTensor() = output_2d.reshape(output_shape);
402
403 return GraphNode::eval();
404}
405
Tai Lya4d748b2023-03-28 22:06:56 +0000406template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000407OpCast<Rank, InDtype, OutDtype>::OpCast(SubgraphTraverser* sgt_, TosaAttributeBase* attribute_, uint64_t id_)
Kevin Chengacb550f2021-06-29 15:32:19 -0700408 : GraphNode(sgt_, Op_CAST, id_)
Eric Kunzee5e26762020-10-13 16:11:07 -0700409{
410 setRequiredOperands(1, 1);
411 setRequiredRank(0, 6);
412}
413
Tai Lya4d748b2023-03-28 22:06:56 +0000414template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700415OpCast<Rank, InDtype, OutDtype>::~OpCast()
416{}
417
Tai Lya4d748b2023-03-28 22:06:56 +0000418template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700419int OpCast<Rank, InDtype, OutDtype>::checkTensorAttributes()
420{
Jerry Gea793f462023-04-11 00:05:02 +0000421 // Check Tosa Level
422 auto tosa_level = g_func_config.tosa_level;
423 LEVEL_CHECK(Rank <= tosa_level.MAX_RANK, "Rank should be smaller than or equal to MAX_RANK");
424
Eric Kunzee5e26762020-10-13 16:11:07 -0700425 if (validateRequiredOperands())
426 return 1;
427
428 if (validateRequiredRank(inputs[0]) || validateRequiredRank(outputs[0]))
429 {
430 return 1;
431 }
432
433 // output and input must be the same rank and size
434 if (inputs[0]->matchRankSize(*outputs[0]))
435 {
436 printNodeValidationError("OpCast: input and output rank/size must match");
437 return 1;
438 }
439
440 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
441 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
442
443 ASSERT_MEM(in && out);
444
445 return 0;
446}
447
Tai Lya4d748b2023-03-28 22:06:56 +0000448template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700449int OpCast<Rank, InDtype, OutDtype>::eval()
450{
451 this->out->getTensor() = this->in->getTensor().unaryExpr(cast_helper.get_fcn());
452
453 return GraphNode::eval();
454}
455
Tai Lya4d748b2023-03-28 22:06:56 +0000456template <TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700457CastHelper<InDtype, OutDtype>::CastHelper()
458{
459 fcn = [](InEigenType in) -> OutEigenType {
460 OutEigenType out = (OutEigenType)in; // implicit sign_extend() if sizeof(out_t) >= sizeof(in_t)
Eric Kunzee5e26762020-10-13 16:11:07 -0700461 return out;
462 };
463}
464
Tai Lya4d748b2023-03-28 22:06:56 +0000465template <TOSA_REF_TYPE InDtype>
466CastHelper<InDtype, TOSA_REF_TYPE_BOOL>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700467{
468 fcn = [](InEigenType in) -> bool { return (in != 0) ? true : false; };
469}
470
Tai Lya4d748b2023-03-28 22:06:56 +0000471template <TOSA_REF_TYPE OutDtype>
472CastHelper<TOSA_REF_TYPE_BOOL, OutDtype>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700473{
474 fcn = [](bool in) -> OutEigenType {
475 OutEigenType out = in ? (OutEigenType)1 : (OutEigenType)0;
476 return out;
477 };
478}
479
Tai Lya4d748b2023-03-28 22:06:56 +0000480template <TOSA_REF_TYPE InDtype>
481CastHelper<InDtype, TOSA_REF_TYPE_FP16>::CastHelper()
James Ward8b390432022-08-12 20:48:56 +0100482{
James Ward736fd1a2023-01-23 17:13:37 +0000483 // Integer data converted to fp16 (stored as fp32)
James Ward8b390432022-08-12 20:48:56 +0100484 fcn = [](InEigenType in) -> float {
James Ward736fd1a2023-01-23 17:13:37 +0000485 half_float::half h = half_float::half(in);
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000486 float out = half_float::half_cast<float, half_float::half>(h);
James Ward736fd1a2023-01-23 17:13:37 +0000487 return out;
488 };
489}
490
Tai Lya4d748b2023-03-28 22:06:56 +0000491CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000492{
493 // fp32 data converted to fp16 (stored as fp32)
494 fcn = [](float in) -> float {
Tai Lya4d748b2023-03-28 22:06:56 +0000495 float out = fpTrunc<TOSA_REF_TYPE_FP16>(in); // truncate required for conversion from higher precision
James Ward736fd1a2023-01-23 17:13:37 +0000496 return out;
497 };
498}
499
Tai Lya4d748b2023-03-28 22:06:56 +0000500template <TOSA_REF_TYPE InDtype>
501CastHelper<InDtype, TOSA_REF_TYPE_BF16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000502{
503 // Integer data converted to bf16 (stored as fp32)
504 fcn = [](InEigenType in) -> float {
505 float out = (float)in; // default cast to float is round_to_nearest_float()
506 return out;
507 };
508}
509
Tai Lya4d748b2023-03-28 22:06:56 +0000510CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_BF16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000511{
512 // fp32 data converted to bf16 (stored as fp32)
513 fcn = [](float in) -> float {
Tai Lya4d748b2023-03-28 22:06:56 +0000514 return fpTrunc<TOSA_REF_TYPE_BF16>(in); // truncate required for conversions from higher precision
James Ward8b390432022-08-12 20:48:56 +0100515 };
516}
517
Tai Lya4d748b2023-03-28 22:06:56 +0000518template <TOSA_REF_TYPE OutDtype>
519CastHelper<TOSA_REF_TYPE_FP16, OutDtype>::CastHelper()
James Ward8b390432022-08-12 20:48:56 +0100520{
James Ward736fd1a2023-01-23 17:13:37 +0000521 // fp16 data (stored as fp32) converted to integer
James Ward8b390432022-08-12 20:48:56 +0100522 fcn = [](float in) -> OutEigenType {
James Ward736fd1a2023-01-23 17:13:37 +0000523 // Cast from float representation back to half_float before rounding
524 half_float::half h = half_float::half(in);
Jerry Ged6a04612023-12-15 22:45:39 +0000525 if (h >= half_float::half(float(OutMax)))
526 return OutMax;
527
528 if (h <= half_float::half(float(OutMin)))
529 return OutMin;
530
531 h = std::rint(h);
532 OutEigenType out = half_float::half_cast<OutEigenType, half_float::half>(h);
533
James Ward8b390432022-08-12 20:48:56 +0100534 return out;
535 };
536}
537
Tai Lya4d748b2023-03-28 22:06:56 +0000538CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP32>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000539{
540 // No-op since fp16 values treated internally as their fp32 representation
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000541 fcn = [](float in) -> OutEigenType { return in; };
James Ward736fd1a2023-01-23 17:13:37 +0000542}
543
Tai Lya4d748b2023-03-28 22:06:56 +0000544template <TOSA_REF_TYPE OutDtype>
545CastHelper<TOSA_REF_TYPE_BF16, OutDtype>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000546{
547 // bf16 data (stored as fp32) converted to integer
548 fcn = [](float in) -> OutEigenType {
Jerry Ged6a04612023-12-15 22:45:39 +0000549 if (in >= float(OutMax))
550 return OutMax;
551
552 if (in <= float(OutMin))
553 return OutMin;
554
555 OutEigenType out = std::rint(in);
James Ward736fd1a2023-01-23 17:13:37 +0000556 return out;
557 };
558}
559
Tai Lya4d748b2023-03-28 22:06:56 +0000560CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP32>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000561{
562 // No-op since bf16 values treated as truncated fp32 internally
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000563 fcn = [](InEigenType in) -> OutEigenType { return in; };
James Ward736fd1a2023-01-23 17:13:37 +0000564}
565
Tai Lya4d748b2023-03-28 22:06:56 +0000566template <TOSA_REF_TYPE InDtype>
567CastHelper<InDtype, TOSA_REF_TYPE_FP32>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700568{
James Ward736fd1a2023-01-23 17:13:37 +0000569 // Integer data converted to fp32
Eric Kunzee5e26762020-10-13 16:11:07 -0700570 fcn = [](InEigenType in) -> float {
571 float out = (OutEigenType)in; // default cast to float is round_to_nearest_float()
572 return out;
573 };
574}
575
Tai Lya4d748b2023-03-28 22:06:56 +0000576template <TOSA_REF_TYPE OutDtype>
577CastHelper<TOSA_REF_TYPE_FP32, OutDtype>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700578{
James Ward736fd1a2023-01-23 17:13:37 +0000579 // fp32 data converted to integer
Eric Kunzee5e26762020-10-13 16:11:07 -0700580 fcn = [](float in) -> OutEigenType {
Jerry Ge44827be2023-12-15 00:05:37 +0000581 if (in >= float(OutMax))
582 return OutMax;
583
584 if (in <= float(OutMin))
585 return OutMin;
586
Eric Kunze57bc0792023-01-25 10:05:51 -0800587 OutEigenType out = std::rint(in);
Eric Kunzee5e26762020-10-13 16:11:07 -0700588 return out;
589 };
590}
591
Tai Lya4d748b2023-03-28 22:06:56 +0000592template <TOSA_REF_TYPE OutDtype>
Won Jeon2c34b462024-02-06 18:37:00 +0000593CastHelper<TOSA_REF_TYPE_FP8E4M3, OutDtype>::CastHelper()
594{
595 // fp8e4m3 data (stored as fp32) converted to integer
596 fcn = [](float in) -> OutEigenType {
597 if (in >= float(OutMax))
598 return OutMax;
599 if (in <= float(OutMin))
600 return OutMin;
601
602 OutEigenType out = std::rint(in);
603 return out;
604 };
605}
606
607CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_FP16>::CastHelper()
608{
609 // fp8e4m3 data (stored as fp32) converted to fp16 (stored as fp32)
610 fcn = [](float in) -> float {
611 half_float::half h = half_float::half(in);
612 float out = half_float::half_cast<half_float::half, float>(h);
613 return out;
614 };
615}
616
617CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_BF16>::CastHelper()
618{
619 // fp8e4m3 data (stored as fp32) converted to bf16 (stored as fp32)
620 fcn = [](float in) -> float { return (float)in; };
621}
622
623CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_FP32>::CastHelper()
624{
625 // fp8e4m3 data (stored as fp32) converted to fp32
626 fcn = [](InEigenType in) -> OutEigenType { return in; };
627}
628
629template <TOSA_REF_TYPE OutDtype>
630CastHelper<TOSA_REF_TYPE_FP8E5M2, OutDtype>::CastHelper()
631{
632 // fp8e5m2 data (stored as fp32) converted to integer
633 fcn = [](float in) -> OutEigenType {
634 if (in >= float(OutMax))
635 return OutMax;
636 if (in <= float(OutMin))
637 return OutMin;
638
639 OutEigenType out = std::rint(in);
640 return out;
641 };
642}
643
644CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_FP16>::CastHelper()
645{
646 // fp8e5m2 data (stored as fp32) converted to fp16 (stored as fp32)
647 fcn = [](float in) -> float {
648 half_float::half h = half_float::half(in);
649 float out = half_float::half_cast<half_float::half, float>(h);
650 return out;
651 };
652}
653
654CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_BF16>::CastHelper()
655{
656 // fp8e5m2 data (stored as fp32) converted to bf16 (stored as fp32)
657 fcn = [](float in) -> float { return (float)in; };
658}
659
660CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_FP32>::CastHelper()
661{
662 // fp8e5m2 data (stored as fp32) converted to fp32
663 fcn = [](InEigenType in) -> OutEigenType { return in; };
664}
665
666template <TOSA_REF_TYPE InDtype>
667CastHelper<InDtype, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
668{
669 // Integer data converted to fp8e4m3 (stored as fp32)
670 fcn = [](InEigenType in) -> float {
671 auto f = static_cast<fp32>(static_cast<fp8e4m3>(float(in)));
672 float out = static_cast<float>(f);
673 return out;
674 };
675}
676
677CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
678{
679 // fp16 data (stored as fp32) converted to fp8e4m3 (stored as fp32)
680 fcn = [](float in) -> float {
681 auto f = static_cast<fp32>(static_cast<fp8e4m3>(in));
682 float out = static_cast<float>(f);
683 return out;
684 };
685}
686
687CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
688{
689 // bf16 data (stored as fp32) converted to fp8e4m3 (stored as fp32)
690 fcn = [](float in) -> float {
691 auto f = static_cast<fp32>(static_cast<fp8e4m3>(in));
692 float out = static_cast<float>(f);
693 return out;
694 };
695}
696
697CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
698{
699 // fp32 data converted to fp8e4m3 (stored as fp32)
700 fcn = [](float in) -> float {
701 auto f = static_cast<fp32>(static_cast<fp8e4m3>(in));
702 float out = static_cast<float>(f);
703 return out;
704 };
705}
706
707template <TOSA_REF_TYPE InDtype>
708CastHelper<InDtype, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
709{
710 // Integer data converted to fp8e5m2 (stored as fp32)
711 fcn = [](InEigenType in) -> float {
712 auto f = static_cast<fp32>(static_cast<fp8e5m2>(float(in)));
713 float out = static_cast<float>(f);
714 return out;
715 };
716}
717
718CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
719{
720 // fp16 data (stored as fp32) converted to fp8e5m2 (stored as fp32)
721 fcn = [](float in) -> float {
722 auto f = static_cast<fp32>(static_cast<fp8e5m2>(in));
723 float out = static_cast<float>(f);
724 return out;
725 };
726}
727
728CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
729{
730 // bf16 data (stored as fp32) converted to fp8e5m2 (stored as fp32)
731 fcn = [](float in) -> float {
732 auto f = static_cast<fp32>(static_cast<fp8e5m2>(in));
733 float out = static_cast<float>(f);
734 return out;
735 };
736}
737
738CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
739{
740 // fp32 data converted to fp8e5m2 (stored as fp32)
741 fcn = [](float in) -> float {
742 auto f = static_cast<fp32>(static_cast<fp8e5m2>(in));
743 float out = static_cast<float>(f);
744 return out;
745 };
746}
747
748template <TOSA_REF_TYPE OutDtype>
Tai Lya4d748b2023-03-28 22:06:56 +0000749CastHelper<TOSA_REF_TYPE_FP64, OutDtype>::CastHelper()
750{
751 switch (OutDtype)
752 {
753 case TOSA_REF_TYPE_INT8:
754 case TOSA_REF_TYPE_INT16:
755 case TOSA_REF_TYPE_INT32:
756 // fp64 data converted to integer
757 fcn = [](InEigenType in) -> OutEigenType {
Jerry Ged6a04612023-12-15 22:45:39 +0000758 if (in >= double(OutMax))
759 return OutMax;
760
761 if (in <= double(OutMin))
762 return OutMin;
763
Tai Lya4d748b2023-03-28 22:06:56 +0000764 OutEigenType out = std::rint(in);
Tai Lya4d748b2023-03-28 22:06:56 +0000765 return out;
766 };
767 break;
768 case TOSA_REF_TYPE_FP64:
769 // no op
770 fcn = [](InEigenType in) -> OutEigenType { return in; };
771 break;
772 default:
773 ASSERT_MSG(false, "unsupported TOSA_REF_TYPE %s", EnumNameTOSAREFTYPE(OutDtype));
774 }
775}
776
Eric Kunzee5e26762020-10-13 16:11:07 -0700777// template explicit instantiation
778DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT8);
779DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT16);
780DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT32);
781DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BOOL);
782DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT16);
783DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT32);
James Ward8b390432022-08-12 20:48:56 +0100784DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000785DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100786DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700787DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BOOL);
788DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT8);
789DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT32);
James Ward8b390432022-08-12 20:48:56 +0100790DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000791DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100792DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700793DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BOOL);
794DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT8);
795DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT16);
James Ward8b390432022-08-12 20:48:56 +0100796DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000797DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100798DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP32);
James Ward8b390432022-08-12 20:48:56 +0100799DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT8);
800DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT16);
801DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000802DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP32);
James Ward24dbc422022-10-19 12:20:31 +0100803DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT8);
804DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT16);
805DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000806DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP32);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100807DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT8);
808DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT16);
809DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000810DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP16);
811DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, BF16);
Tai Lya4d748b2023-03-28 22:06:56 +0000812DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT8);
813DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT16);
814DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT32);
815DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, FP64);
816DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP64);
817DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP64);
818DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP64);
Won Jeon2c34b462024-02-06 18:37:00 +0000819DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP8E4M3);
820DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP8E5M2);
821DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, FP16);
822DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, BF16);
823DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, FP32);
824DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, FP16);
825DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, BF16);
826DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, FP32);
827DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP8E4M3);
828DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP8E5M2);
829DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP8E4M3);
830DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP8E5M2);
Eric Kunzee5e26762020-10-13 16:11:07 -0700831
Kevin Cheng3a478572021-01-22 17:21:02 -0800832DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT8);
833DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT16);
834DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT32);
835DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700836DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT16);
837DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800838DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700839DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT16);
840DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800841DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700842DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT16);
843DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800844DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100845DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT16);
846DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT16, INT16);
Kevin Cheng3a478572021-01-22 17:21:02 -0800847DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, UINT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100848DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT8);
849DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT16);