blob: d58cfebf636cb1dbe4645e988d89c8da5f364103 [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);
40}
41
Tai Lya4d748b2023-03-28 22:06:56 +000042template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -070043OpRescale<Rank, InDtype, OutDtype>::~OpRescale()
44{
45 if (attribute)
46 delete attribute;
47}
48
Tai Lya4d748b2023-03-28 22:06:56 +000049template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -070050int OpRescale<Rank, InDtype, OutDtype>::checkTensorAttributes()
51{
Jerry Gea793f462023-04-11 00:05:02 +000052 // Check Tosa Level
53 auto tosa_level = g_func_config.tosa_level;
54 LEVEL_CHECK(Rank <= tosa_level.MAX_RANK, "Rank should be smaller than or equal to MAX_RANK");
55
Eric Kunzee5e26762020-10-13 16:11:07 -070056 if (validateRequiredOperands())
57 return 1;
58
Eric Kunzee5e26762020-10-13 16:11:07 -070059 // output and input must be the same rank and size
60 if (inputs[0]->matchRankSize(*outputs[0]))
61 {
62 printNodeValidationError("OpRescale: input and output rank/size must match");
63 return 1;
64 }
65
66 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
67 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
68
69 ASSERT_MEM(in && out);
70
Tai Ly6e1e2bc2024-03-01 20:59:32 +000071 multiplierI32 = dynamic_cast<TosaReference::TensorTemplate<TMultiplierI32>*>(inputs[1]);
72 multiplierI16 = dynamic_cast<TosaReference::TensorTemplate<TMultiplierI16>*>(inputs[1]);
73 shift = dynamic_cast<TosaReference::TensorTemplate<TShift>*>(inputs[2]);
74 ASSERT_MEM(shift);
75
76 if (attribute->scale32())
77 {
78 ASSERT_MEM(multiplierI32);
79 }
80 else
81 {
82 ASSERT_MEM(multiplierI16);
83 }
84
Tai Lya4d748b2023-03-28 22:06:56 +000085 if ((InDtype != TOSA_REF_TYPE_INT8) && (InDtype != TOSA_REF_TYPE_UINT8) && (InDtype != TOSA_REF_TYPE_UINT16) &&
86 (attribute->input_zp() != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -070087 {
Tai Lya4d748b2023-03-28 22:06:56 +000088 printNodeValidationError("OpRescale: Input TOSA_REF_TYPE not INT8/UINT8/UINT16 and zero point not 0");
Kevin Chengcc61be32021-10-14 17:09:57 -070089 return 1;
90 }
91
Tai Lya4d748b2023-03-28 22:06:56 +000092 if ((OutDtype != TOSA_REF_TYPE_INT8) && (OutDtype != TOSA_REF_TYPE_UINT8) && (OutDtype != TOSA_REF_TYPE_UINT16) &&
93 (attribute->output_zp() != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -070094 {
Tai Lya4d748b2023-03-28 22:06:56 +000095 printNodeValidationError("OpRescale: Output TOSA_REF_TYPE not INT8/UINT8/UINT16 and zero point not 0");
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +010096 return 1;
97 }
98
Tai Lya4d748b2023-03-28 22:06:56 +000099 if ((InDtype == TOSA_REF_TYPE_UINT16) && ((attribute->input_zp() != 0) && (attribute->input_zp() != 32768)))
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100100 {
Tai Lya4d748b2023-03-28 22:06:56 +0000101 printNodeValidationError("OpRescale: Input TOSA_REF_TYPE UINT16 and zero point not 0 or 32768");
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100102 return 1;
103 }
104
Tai Lya4d748b2023-03-28 22:06:56 +0000105 if ((OutDtype == TOSA_REF_TYPE_UINT16) && ((attribute->output_zp() != 0) && (attribute->output_zp() != 32768)))
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100106 {
Tai Lya4d748b2023-03-28 22:06:56 +0000107 printNodeValidationError("OpRescale: Output TOSA_REF_TYPE UINT16 and zero point not 0 or 32768");
Kevin Chengcc61be32021-10-14 17:09:57 -0700108 return 1;
109 }
110
Tai Lya4d748b2023-03-28 22:06:56 +0000111 if (attribute->scale32() && (InDtype == TOSA_REF_TYPE_INT48))
Kevin Chengcc61be32021-10-14 17:09:57 -0700112 {
113 printNodeValidationError("OpRescale: Scale set to true but input type is INT48");
114 return 1;
115 }
116
117 if ((!attribute->scale32()) && attribute->double_round())
118 {
119 printNodeValidationError("OpRescale: Scale set to false but double round set to true");
120 return 1;
121 }
122
Eric Kunzee5e26762020-10-13 16:11:07 -0700123 return 0;
124}
125
Eric Kunzea8098c02023-09-07 00:31:54 +0000126// helpers to convert types
127static int64_t zero_extend(int8_t val)
128{
129 uint8_t* rval = reinterpret_cast<uint8_t*>(&val);
130 return static_cast<int64_t>(*rval);
131}
132static int64_t zero_extend(int16_t val)
133{
134 uint16_t* rval = reinterpret_cast<uint16_t*>(&val);
135 return static_cast<int64_t>(*rval);
136}
137
Tai Lya4d748b2023-03-28 22:06:56 +0000138template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700139int OpRescale<Rank, InDtype, OutDtype>::eval()
140{
Tai Ly6e1e2bc2024-03-01 20:59:32 +0000141 int32_t input_zp = attribute->input_zp();
142 int32_t output_zp = attribute->output_zp();
143 std::vector<int32_t> multiplier;
144 std::vector<int32_t> shift;
145 bool scale32 = attribute->scale32();
146 bool double_round = attribute->double_round();
147 bool per_channel = attribute->per_channel();
148 bool input_unsigned = attribute->input_unsigned();
149 bool output_unsigned = attribute->output_unsigned();
Eric Kunzee5e26762020-10-13 16:11:07 -0700150
Eric Kunzee5e26762020-10-13 16:11:07 -0700151 // reshape [d0, d1, ..., dn] into [d0 * d1 ..., dn]
152 Eigen::array<Eigen::Index, 2> shape_2d;
153 shape_2d[0] = 1;
154 if (Rank > 0)
155 {
156 for (int i = 0; i < Rank - 1; i++)
157 {
158 shape_2d[0] *= this->in->getShape()[i];
159 }
160 shape_2d[1] = this->in->getShape()[Rank - 1];
161 }
162 else
163 {
164 shape_2d[1] = 1;
165 }
166 ETensor2<InEigenType> input_reshaped = this->in->getTensor().reshape(shape_2d);
167
168 ETensor2<OutEigenType> output_2d(shape_2d);
169
Tai Ly6e1e2bc2024-03-01 20:59:32 +0000170 if (scale32)
171 {
172 auto multiplier_val = this->multiplierI32->getTensor();
173 for (int i = 0; i < multiplier_val.size(); i++)
174 {
175 multiplier.push_back(static_cast<int32_t>(multiplier_val(i)));
176 }
177 }
178 else
179 {
180 auto multiplier_val = this->multiplierI16->getTensor();
181 for (int i = 0; i < multiplier_val.size(); i++)
182 {
183 multiplier.push_back(static_cast<int32_t>(multiplier_val(i)));
184 }
185 }
186 auto shift_val = this->shift->getTensor();
187 for (int i = 0; i < shift_val.size(); i++)
188 {
189 shift.push_back(static_cast<int32_t>(shift_val(i)));
190 }
191
Eric Kunzee5e26762020-10-13 16:11:07 -0700192 if (per_channel)
193 {
194 ETensor2<InEigenType> curr_channel_slice_prescaled;
195 ETensor2<OutEigenType> curr_channel_slice_postscaled;
196 int32_t channel_multiplier, channel_shift;
197 Eigen::array<Eigen::Index, 2> begin, size;
198 size = Eigen::array<Eigen::Index, 2>({ shape_2d[0], 1 });
Kevin Chengacb550f2021-06-29 15:32:19 -0700199 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700200 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700201 for (int32_t i = 0; i < shape_2d[1]; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700202 {
Eric Kunzea8098c02023-09-07 00:31:54 +0000203 begin = Eigen::array<Eigen::Index, 2>({ 0, i });
204 curr_channel_slice_prescaled = input_reshaped.slice(begin, size);
205 channel_multiplier = multiplier[i];
206 channel_shift = shift[i];
207 curr_channel_slice_postscaled = curr_channel_slice_prescaled.unaryExpr(
208 [input_zp, output_zp, channel_multiplier, channel_shift, double_round, scale32, input_unsigned,
209 output_unsigned](InEigenType in_val) -> OutEigenType {
210 int64_t input_zp_shifted;
211 if (input_unsigned)
212 {
213 int64_t in_val64;
214 int64_t in_zp64;
215 switch (GetNumBits<InDtype>::value)
216 {
217 case 8:
218 in_val64 = zero_extend(static_cast<int8_t>(in_val));
219 in_zp64 = zero_extend(static_cast<int8_t>(input_zp));
220 break;
221 case 16:
222 in_val64 = zero_extend(static_cast<int16_t>(in_val));
223 in_zp64 = zero_extend(static_cast<int16_t>(input_zp));
224 break;
225 default:
226 in_val64 = static_cast<int64_t>(in_val);
227 in_zp64 = static_cast<int64_t>(input_zp);
228 break;
229 }
230 input_zp_shifted = in_val64 - in_zp64;
231 }
232 else
233 {
234 input_zp_shifted = in_val - input_zp;
235 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700236 int32_t scaled;
237 if (scale32)
Eric Kunzea8098c02023-09-07 00:31:54 +0000238 scaled = TosaReference::QuantUtil::apply_scale_32(static_cast<int32_t>(input_zp_shifted),
239 channel_multiplier, channel_shift,
240 double_round);
Kevin Chengacb550f2021-06-29 15:32:19 -0700241 else
242 scaled = TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, channel_multiplier,
243 channel_shift);
Eric Kunzea8098c02023-09-07 00:31:54 +0000244 int64_t output_zp_extended;
245 if (output_unsigned)
246 {
247 switch (GetNumBits<OutDtype>::value)
248 {
249 case 8:
250 output_zp_extended = zero_extend(static_cast<int8_t>(output_zp));
251 break;
252 case 16:
253 output_zp_extended = zero_extend(static_cast<int16_t>(output_zp));
254 break;
255 default:
256 output_zp_extended = static_cast<int64_t>(output_zp);
257 break;
258 }
259 }
260 else
261 {
262 output_zp_extended = static_cast<int64_t>(output_zp);
263 }
264 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp_extended;
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000265 int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
266 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
267 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
268 {
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000269 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" +
270 std::to_string(output_zp) + "] not in i32 range";
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000271 throw desc;
272 }
273 OutEigenType out_val = static_cast<OutEigenType>(res_in_64);
Kevin Chengacb550f2021-06-29 15:32:19 -0700274 out_val = std::max<OutEigenType>(out_val, QMin);
275 out_val = std::min<OutEigenType>(out_val, QMax);
276 return out_val;
277 });
278
279 for (int32_t j = 0; j < shape_2d[0]; j++)
280 {
281 output_2d(j, i) = curr_channel_slice_postscaled(j, 0);
282 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700283 }
284 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700285 catch (std::string desc)
286 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000287 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700288 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700289 }
290 else
291 {
292 int32_t tensor_multiplier = multiplier[0];
293 int32_t tensor_shift = shift[0];
Kevin Chengacb550f2021-06-29 15:32:19 -0700294 try
295 {
Eric Kunzea8098c02023-09-07 00:31:54 +0000296 output_2d =
297 input_reshaped.unaryExpr([input_zp, output_zp, tensor_multiplier, tensor_shift, double_round, scale32,
298 input_unsigned, output_unsigned](InEigenType in_val) -> OutEigenType {
299 int64_t input_zp_shifted;
300 if (input_unsigned)
301 {
302 int64_t in_val64;
303 int64_t in_zp64;
304 switch (GetNumBits<InDtype>::value)
305 {
306 case 8:
307 in_val64 = zero_extend(static_cast<int8_t>(in_val));
308 in_zp64 = zero_extend(static_cast<int8_t>(input_zp));
309 break;
310 case 16:
311 in_val64 = zero_extend(static_cast<int16_t>(in_val));
312 in_zp64 = zero_extend(static_cast<int16_t>(input_zp));
313 break;
314 default:
315 in_val64 = static_cast<int64_t>(in_val);
316 in_zp64 = static_cast<int64_t>(input_zp);
317 break;
318 }
319 input_zp_shifted = in_val64 - in_zp64;
320 }
321 else
322 {
323 input_zp_shifted = in_val - input_zp;
324 }
325 int32_t scaled;
326 if (scale32)
327 scaled = TosaReference::QuantUtil::apply_scale_32(input_zp_shifted, tensor_multiplier,
328 tensor_shift, double_round);
329 else
330 scaled =
331 TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, tensor_multiplier, tensor_shift);
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000332
Eric Kunzea8098c02023-09-07 00:31:54 +0000333 int64_t output_zp_extended;
334 if (output_unsigned)
335 {
336 switch (GetNumBits<OutDtype>::value)
337 {
338 case 8:
339 output_zp_extended = zero_extend(static_cast<int8_t>(output_zp));
340 break;
341 case 16:
342 output_zp_extended = zero_extend(static_cast<int16_t>(output_zp));
343 break;
344 default:
345 output_zp_extended = static_cast<int64_t>(output_zp);
346 break;
347 }
348 }
349 else
350 {
351 output_zp_extended = static_cast<int64_t>(output_zp);
352 }
353 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp_extended;
354 int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
355 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
356 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
357 {
358 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" +
359 std::to_string(output_zp) + "] not in i32 range";
360 throw desc;
361 }
362
363 OutEigenType out_val = static_cast<OutEigenType>(res_in_64);
364 out_val = std::max<OutEigenType>(out_val, QMin);
365 out_val = std::min<OutEigenType>(out_val, QMax);
366 return out_val;
367 });
Kevin Chengacb550f2021-06-29 15:32:19 -0700368 }
369 catch (std::string desc)
370 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000371 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700372 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700373 }
374
375 // reshape [d0 * d1 ..., dn] back to [d0, d1, ..., dn]
376 Eigen::array<Eigen::Index, Rank> output_shape;
377 for (int i = 0; i < Rank; i++)
378 {
379 output_shape[i] = this->out->getShape()[i];
380 }
381 this->out->getTensor() = output_2d.reshape(output_shape);
382
383 return GraphNode::eval();
384}
385
Tai Lya4d748b2023-03-28 22:06:56 +0000386template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000387OpCast<Rank, InDtype, OutDtype>::OpCast(SubgraphTraverser* sgt_, TosaAttributeBase* attribute_, uint64_t id_)
Kevin Chengacb550f2021-06-29 15:32:19 -0700388 : GraphNode(sgt_, Op_CAST, id_)
Eric Kunzee5e26762020-10-13 16:11:07 -0700389{
390 setRequiredOperands(1, 1);
391 setRequiredRank(0, 6);
392}
393
Tai Lya4d748b2023-03-28 22:06:56 +0000394template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700395OpCast<Rank, InDtype, OutDtype>::~OpCast()
396{}
397
Tai Lya4d748b2023-03-28 22:06:56 +0000398template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700399int OpCast<Rank, InDtype, OutDtype>::checkTensorAttributes()
400{
Jerry Gea793f462023-04-11 00:05:02 +0000401 // Check Tosa Level
402 auto tosa_level = g_func_config.tosa_level;
403 LEVEL_CHECK(Rank <= tosa_level.MAX_RANK, "Rank should be smaller than or equal to MAX_RANK");
404
Eric Kunzee5e26762020-10-13 16:11:07 -0700405 if (validateRequiredOperands())
406 return 1;
407
408 if (validateRequiredRank(inputs[0]) || validateRequiredRank(outputs[0]))
409 {
410 return 1;
411 }
412
413 // output and input must be the same rank and size
414 if (inputs[0]->matchRankSize(*outputs[0]))
415 {
416 printNodeValidationError("OpCast: input and output rank/size must match");
417 return 1;
418 }
419
420 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
421 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
422
423 ASSERT_MEM(in && out);
424
425 return 0;
426}
427
Tai Lya4d748b2023-03-28 22:06:56 +0000428template <int Rank, TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700429int OpCast<Rank, InDtype, OutDtype>::eval()
430{
431 this->out->getTensor() = this->in->getTensor().unaryExpr(cast_helper.get_fcn());
432
433 return GraphNode::eval();
434}
435
Tai Lya4d748b2023-03-28 22:06:56 +0000436template <TOSA_REF_TYPE InDtype, TOSA_REF_TYPE OutDtype>
Eric Kunzee5e26762020-10-13 16:11:07 -0700437CastHelper<InDtype, OutDtype>::CastHelper()
438{
439 fcn = [](InEigenType in) -> OutEigenType {
440 OutEigenType out = (OutEigenType)in; // implicit sign_extend() if sizeof(out_t) >= sizeof(in_t)
Eric Kunzee5e26762020-10-13 16:11:07 -0700441 return out;
442 };
443}
444
Tai Lya4d748b2023-03-28 22:06:56 +0000445template <TOSA_REF_TYPE InDtype>
446CastHelper<InDtype, TOSA_REF_TYPE_BOOL>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700447{
448 fcn = [](InEigenType in) -> bool { return (in != 0) ? true : false; };
449}
450
Tai Lya4d748b2023-03-28 22:06:56 +0000451template <TOSA_REF_TYPE OutDtype>
452CastHelper<TOSA_REF_TYPE_BOOL, OutDtype>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700453{
454 fcn = [](bool in) -> OutEigenType {
455 OutEigenType out = in ? (OutEigenType)1 : (OutEigenType)0;
456 return out;
457 };
458}
459
Tai Lya4d748b2023-03-28 22:06:56 +0000460template <TOSA_REF_TYPE InDtype>
461CastHelper<InDtype, TOSA_REF_TYPE_FP16>::CastHelper()
James Ward8b390432022-08-12 20:48:56 +0100462{
James Ward736fd1a2023-01-23 17:13:37 +0000463 // Integer data converted to fp16 (stored as fp32)
James Ward8b390432022-08-12 20:48:56 +0100464 fcn = [](InEigenType in) -> float {
James Ward736fd1a2023-01-23 17:13:37 +0000465 half_float::half h = half_float::half(in);
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000466 float out = half_float::half_cast<float, half_float::half>(h);
James Ward736fd1a2023-01-23 17:13:37 +0000467 return out;
468 };
469}
470
Tai Lya4d748b2023-03-28 22:06:56 +0000471CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000472{
473 // fp32 data converted to fp16 (stored as fp32)
474 fcn = [](float in) -> float {
Tai Lya4d748b2023-03-28 22:06:56 +0000475 float out = fpTrunc<TOSA_REF_TYPE_FP16>(in); // truncate required for conversion from higher precision
James Ward736fd1a2023-01-23 17:13:37 +0000476 return out;
477 };
478}
479
Tai Lya4d748b2023-03-28 22:06:56 +0000480template <TOSA_REF_TYPE InDtype>
481CastHelper<InDtype, TOSA_REF_TYPE_BF16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000482{
483 // Integer data converted to bf16 (stored as fp32)
484 fcn = [](InEigenType in) -> float {
485 float out = (float)in; // default cast to float is round_to_nearest_float()
486 return out;
487 };
488}
489
Tai Lya4d748b2023-03-28 22:06:56 +0000490CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_BF16>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000491{
492 // fp32 data converted to bf16 (stored as fp32)
493 fcn = [](float in) -> float {
Tai Lya4d748b2023-03-28 22:06:56 +0000494 return fpTrunc<TOSA_REF_TYPE_BF16>(in); // truncate required for conversions from higher precision
James Ward8b390432022-08-12 20:48:56 +0100495 };
496}
497
Tai Lya4d748b2023-03-28 22:06:56 +0000498template <TOSA_REF_TYPE OutDtype>
499CastHelper<TOSA_REF_TYPE_FP16, OutDtype>::CastHelper()
James Ward8b390432022-08-12 20:48:56 +0100500{
James Ward736fd1a2023-01-23 17:13:37 +0000501 // fp16 data (stored as fp32) converted to integer
James Ward8b390432022-08-12 20:48:56 +0100502 fcn = [](float in) -> OutEigenType {
James Ward736fd1a2023-01-23 17:13:37 +0000503 // Cast from float representation back to half_float before rounding
504 half_float::half h = half_float::half(in);
Jerry Ged6a04612023-12-15 22:45:39 +0000505 if (h >= half_float::half(float(OutMax)))
506 return OutMax;
507
508 if (h <= half_float::half(float(OutMin)))
509 return OutMin;
510
511 h = std::rint(h);
512 OutEigenType out = half_float::half_cast<OutEigenType, half_float::half>(h);
513
James Ward8b390432022-08-12 20:48:56 +0100514 return out;
515 };
516}
517
Tai Lya4d748b2023-03-28 22:06:56 +0000518CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP32>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000519{
520 // No-op since fp16 values treated internally as their fp32 representation
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000521 fcn = [](float in) -> OutEigenType { return in; };
James Ward736fd1a2023-01-23 17:13:37 +0000522}
523
Tai Lya4d748b2023-03-28 22:06:56 +0000524template <TOSA_REF_TYPE OutDtype>
525CastHelper<TOSA_REF_TYPE_BF16, OutDtype>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000526{
527 // bf16 data (stored as fp32) converted to integer
528 fcn = [](float in) -> OutEigenType {
Jerry Ged6a04612023-12-15 22:45:39 +0000529 if (in >= float(OutMax))
530 return OutMax;
531
532 if (in <= float(OutMin))
533 return OutMin;
534
535 OutEigenType out = std::rint(in);
James Ward736fd1a2023-01-23 17:13:37 +0000536 return out;
537 };
538}
539
Tai Lya4d748b2023-03-28 22:06:56 +0000540CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP32>::CastHelper()
James Ward736fd1a2023-01-23 17:13:37 +0000541{
542 // No-op since bf16 values treated as truncated fp32 internally
Jerry Ge9c9c8da2023-07-19 23:08:16 +0000543 fcn = [](InEigenType in) -> OutEigenType { return in; };
James Ward736fd1a2023-01-23 17:13:37 +0000544}
545
Tai Lya4d748b2023-03-28 22:06:56 +0000546template <TOSA_REF_TYPE InDtype>
547CastHelper<InDtype, TOSA_REF_TYPE_FP32>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700548{
James Ward736fd1a2023-01-23 17:13:37 +0000549 // Integer data converted to fp32
Eric Kunzee5e26762020-10-13 16:11:07 -0700550 fcn = [](InEigenType in) -> float {
551 float out = (OutEigenType)in; // default cast to float is round_to_nearest_float()
552 return out;
553 };
554}
555
Tai Lya4d748b2023-03-28 22:06:56 +0000556template <TOSA_REF_TYPE OutDtype>
557CastHelper<TOSA_REF_TYPE_FP32, OutDtype>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700558{
James Ward736fd1a2023-01-23 17:13:37 +0000559 // fp32 data converted to integer
Eric Kunzee5e26762020-10-13 16:11:07 -0700560 fcn = [](float in) -> OutEigenType {
Jerry Ge44827be2023-12-15 00:05:37 +0000561 if (in >= float(OutMax))
562 return OutMax;
563
564 if (in <= float(OutMin))
565 return OutMin;
566
Eric Kunze57bc0792023-01-25 10:05:51 -0800567 OutEigenType out = std::rint(in);
Eric Kunzee5e26762020-10-13 16:11:07 -0700568 return out;
569 };
570}
571
Tai Lya4d748b2023-03-28 22:06:56 +0000572template <TOSA_REF_TYPE OutDtype>
Won Jeon2c34b462024-02-06 18:37:00 +0000573CastHelper<TOSA_REF_TYPE_FP8E4M3, OutDtype>::CastHelper()
574{
575 // fp8e4m3 data (stored as fp32) converted to integer
576 fcn = [](float in) -> OutEigenType {
577 if (in >= float(OutMax))
578 return OutMax;
579 if (in <= float(OutMin))
580 return OutMin;
581
582 OutEigenType out = std::rint(in);
583 return out;
584 };
585}
586
587CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_FP16>::CastHelper()
588{
589 // fp8e4m3 data (stored as fp32) converted to fp16 (stored as fp32)
590 fcn = [](float in) -> float {
591 half_float::half h = half_float::half(in);
592 float out = half_float::half_cast<half_float::half, float>(h);
593 return out;
594 };
595}
596
597CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_BF16>::CastHelper()
598{
599 // fp8e4m3 data (stored as fp32) converted to bf16 (stored as fp32)
600 fcn = [](float in) -> float { return (float)in; };
601}
602
603CastHelper<TOSA_REF_TYPE_FP8E4M3, TOSA_REF_TYPE_FP32>::CastHelper()
604{
605 // fp8e4m3 data (stored as fp32) converted to fp32
606 fcn = [](InEigenType in) -> OutEigenType { return in; };
607}
608
609template <TOSA_REF_TYPE OutDtype>
610CastHelper<TOSA_REF_TYPE_FP8E5M2, OutDtype>::CastHelper()
611{
612 // fp8e5m2 data (stored as fp32) converted to integer
613 fcn = [](float in) -> OutEigenType {
614 if (in >= float(OutMax))
615 return OutMax;
616 if (in <= float(OutMin))
617 return OutMin;
618
619 OutEigenType out = std::rint(in);
620 return out;
621 };
622}
623
624CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_FP16>::CastHelper()
625{
626 // fp8e5m2 data (stored as fp32) converted to fp16 (stored as fp32)
627 fcn = [](float in) -> float {
628 half_float::half h = half_float::half(in);
629 float out = half_float::half_cast<half_float::half, float>(h);
630 return out;
631 };
632}
633
634CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_BF16>::CastHelper()
635{
636 // fp8e5m2 data (stored as fp32) converted to bf16 (stored as fp32)
637 fcn = [](float in) -> float { return (float)in; };
638}
639
640CastHelper<TOSA_REF_TYPE_FP8E5M2, TOSA_REF_TYPE_FP32>::CastHelper()
641{
642 // fp8e5m2 data (stored as fp32) converted to fp32
643 fcn = [](InEigenType in) -> OutEigenType { return in; };
644}
645
646template <TOSA_REF_TYPE InDtype>
647CastHelper<InDtype, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
648{
649 // Integer data converted to fp8e4m3 (stored as fp32)
650 fcn = [](InEigenType in) -> float {
651 auto f = static_cast<fp32>(static_cast<fp8e4m3>(float(in)));
652 float out = static_cast<float>(f);
653 return out;
654 };
655}
656
657CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
658{
659 // fp16 data (stored as fp32) converted to fp8e4m3 (stored as fp32)
660 fcn = [](float in) -> float {
661 auto f = static_cast<fp32>(static_cast<fp8e4m3>(in));
662 float out = static_cast<float>(f);
663 return out;
664 };
665}
666
667CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
668{
669 // bf16 data (stored as fp32) converted to fp8e4m3 (stored as fp32)
670 fcn = [](float in) -> float {
671 auto f = static_cast<fp32>(static_cast<fp8e4m3>(in));
672 float out = static_cast<float>(f);
673 return out;
674 };
675}
676
677CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP8E4M3>::CastHelper()
678{
679 // fp32 data 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
687template <TOSA_REF_TYPE InDtype>
688CastHelper<InDtype, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
689{
690 // Integer data converted to fp8e5m2 (stored as fp32)
691 fcn = [](InEigenType in) -> float {
692 auto f = static_cast<fp32>(static_cast<fp8e5m2>(float(in)));
693 float out = static_cast<float>(f);
694 return out;
695 };
696}
697
698CastHelper<TOSA_REF_TYPE_FP16, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
699{
700 // fp16 data (stored as fp32) converted to fp8e5m2 (stored as fp32)
701 fcn = [](float in) -> float {
702 auto f = static_cast<fp32>(static_cast<fp8e5m2>(in));
703 float out = static_cast<float>(f);
704 return out;
705 };
706}
707
708CastHelper<TOSA_REF_TYPE_BF16, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
709{
710 // bf16 data (stored as fp32) converted to fp8e5m2 (stored as fp32)
711 fcn = [](float in) -> float {
712 auto f = static_cast<fp32>(static_cast<fp8e5m2>(in));
713 float out = static_cast<float>(f);
714 return out;
715 };
716}
717
718CastHelper<TOSA_REF_TYPE_FP32, TOSA_REF_TYPE_FP8E5M2>::CastHelper()
719{
720 // fp32 data 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
728template <TOSA_REF_TYPE OutDtype>
Tai Lya4d748b2023-03-28 22:06:56 +0000729CastHelper<TOSA_REF_TYPE_FP64, OutDtype>::CastHelper()
730{
731 switch (OutDtype)
732 {
733 case TOSA_REF_TYPE_INT8:
734 case TOSA_REF_TYPE_INT16:
735 case TOSA_REF_TYPE_INT32:
736 // fp64 data converted to integer
737 fcn = [](InEigenType in) -> OutEigenType {
Jerry Ged6a04612023-12-15 22:45:39 +0000738 if (in >= double(OutMax))
739 return OutMax;
740
741 if (in <= double(OutMin))
742 return OutMin;
743
Tai Lya4d748b2023-03-28 22:06:56 +0000744 OutEigenType out = std::rint(in);
Tai Lya4d748b2023-03-28 22:06:56 +0000745 return out;
746 };
747 break;
748 case TOSA_REF_TYPE_FP64:
749 // no op
750 fcn = [](InEigenType in) -> OutEigenType { return in; };
751 break;
752 default:
753 ASSERT_MSG(false, "unsupported TOSA_REF_TYPE %s", EnumNameTOSAREFTYPE(OutDtype));
754 }
755}
756
Eric Kunzee5e26762020-10-13 16:11:07 -0700757// template explicit instantiation
758DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT8);
759DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT16);
760DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT32);
761DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BOOL);
762DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT16);
763DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT32);
James Ward8b390432022-08-12 20:48:56 +0100764DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000765DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100766DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700767DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BOOL);
768DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT8);
769DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT32);
James Ward8b390432022-08-12 20:48:56 +0100770DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000771DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100772DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700773DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BOOL);
774DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT8);
775DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT16);
James Ward8b390432022-08-12 20:48:56 +0100776DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000777DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100778DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP32);
James Ward8b390432022-08-12 20:48:56 +0100779DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT8);
780DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT16);
781DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000782DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP32);
James Ward24dbc422022-10-19 12:20:31 +0100783DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT8);
784DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT16);
785DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000786DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP32);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100787DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT8);
788DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT16);
789DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000790DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP16);
791DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, BF16);
Tai Lya4d748b2023-03-28 22:06:56 +0000792DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT8);
793DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT16);
794DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, INT32);
795DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP64, FP64);
796DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP64);
797DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP64);
798DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP64);
Won Jeon2c34b462024-02-06 18:37:00 +0000799DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP8E4M3);
800DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP8E5M2);
801DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, FP16);
802DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, BF16);
803DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E4M3, FP32);
804DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, FP16);
805DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, BF16);
806DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP8E5M2, FP32);
807DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP8E4M3);
808DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP8E5M2);
809DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP8E4M3);
810DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP8E5M2);
Eric Kunzee5e26762020-10-13 16:11:07 -0700811
Kevin Cheng3a478572021-01-22 17:21:02 -0800812DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT8);
813DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT16);
814DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT32);
815DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700816DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT16);
817DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800818DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700819DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT16);
820DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800821DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700822DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT16);
823DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800824DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100825DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT16);
826DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT16, INT16);
Kevin Cheng3a478572021-01-22 17:21:02 -0800827DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, UINT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100828DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT8);
829DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT16);