blob: a3140c35617c32f515175a5766952c0ffde04f6f [file] [log] [blame]
Eric Kunzee5e26762020-10-13 16:11:07 -07001
James Ward8b390432022-08-12 20:48:56 +01002// Copyright (c) 2020-2022, 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"
17#include "quant_util.h"
James Ward736fd1a2023-01-23 17:13:37 +000018#include "arith_util.h"
Eric Kunzee5e26762020-10-13 16:11:07 -070019#include "template_types.h"
20#include <cmath>
James Ward8b390432022-08-12 20:48:56 +010021#include "half.hpp"
Eric Kunzee5e26762020-10-13 16:11:07 -070022
23using namespace TosaReference;
24using namespace Eigen;
25using namespace tosa;
26
27template <int Rank, DType InDtype, DType OutDtype>
Kevin Chengacb550f2021-06-29 15:32:19 -070028OpRescale<Rank, InDtype, OutDtype>::OpRescale(SubgraphTraverser* sgt_,
29 TosaAttributeBase* attribute_,
Kevin Chengacb550f2021-06-29 15:32:19 -070030 uint64_t id_)
31 : GraphNode(sgt_, Op_RESCALE, id_)
Eric Kunzee5e26762020-10-13 16:11:07 -070032{
33 setRequiredOperands(1, 1);
TatWai Chongfd629052022-07-25 04:01:58 +000034 setRequiredRank(0, 6);
Eric Kunzee5e26762020-10-13 16:11:07 -070035 INIT_ATTRIBUTE(Rescale);
36}
37
38template <int Rank, DType InDtype, DType OutDtype>
39OpRescale<Rank, InDtype, OutDtype>::~OpRescale()
40{
41 if (attribute)
42 delete attribute;
43}
44
45template <int Rank, DType InDtype, DType OutDtype>
46int OpRescale<Rank, InDtype, OutDtype>::checkTensorAttributes()
47{
48 if (validateRequiredOperands())
49 return 1;
50
51 if (validateRequiredRank(inputs[0]) || validateRequiredRank(outputs[0]))
52 {
53 return 1;
54 }
55
56 // output and input must be the same rank and size
57 if (inputs[0]->matchRankSize(*outputs[0]))
58 {
59 printNodeValidationError("OpRescale: input and output rank/size must match");
60 return 1;
61 }
62
63 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
64 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
65
66 ASSERT_MEM(in && out);
67
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +010068 if ((InDtype != DType_INT8) && (InDtype != DType_UINT8) && (InDtype != DType_UINT16) && (attribute->input_zp() != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -070069 {
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +010070 printNodeValidationError("OpRescale: Input DType not INT8/UINT8/UINT16 and zero point not 0");
Kevin Chengcc61be32021-10-14 17:09:57 -070071 return 1;
72 }
73
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +010074 if ((OutDtype != DType_INT8) && (OutDtype != DType_UINT8) && (OutDtype != DType_UINT16) && (attribute->output_zp() != 0))
Kevin Chengcc61be32021-10-14 17:09:57 -070075 {
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +010076 printNodeValidationError("OpRescale: Output DType not INT8/UINT8/UINT16 and zero point not 0");
77 return 1;
78 }
79
80 if ((InDtype == DType_UINT16) && ((attribute->input_zp() != 0) && (attribute->input_zp() != 32768)))
81 {
82 printNodeValidationError("OpRescale: Input DType UINT16 and zero point not 0 or 32768");
83 return 1;
84 }
85
86 if ((OutDtype == DType_UINT16) && ((attribute->output_zp() != 0) && (attribute->output_zp() != 32768)))
87 {
88 printNodeValidationError("OpRescale: Output DType UINT16 and zero point not 0 or 32768");
Kevin Chengcc61be32021-10-14 17:09:57 -070089 return 1;
90 }
91
92 if (attribute->scale32() && (InDtype == DType_INT48))
93 {
94 printNodeValidationError("OpRescale: Scale set to true but input type is INT48");
95 return 1;
96 }
97
98 if ((!attribute->scale32()) && attribute->double_round())
99 {
100 printNodeValidationError("OpRescale: Scale set to false but double round set to true");
101 return 1;
102 }
103
Eric Kunzee5e26762020-10-13 16:11:07 -0700104 return 0;
105}
106
107template <int Rank, DType InDtype, DType OutDtype>
108int OpRescale<Rank, InDtype, OutDtype>::eval()
109{
110 int32_t input_zp = attribute->input_zp();
111 int32_t output_zp = attribute->output_zp();
112 std::vector<int32_t> multiplier = attribute->multiplier();
113 std::vector<int32_t> shift = attribute->shift();
Kevin Cheng0f87c952021-03-18 17:41:39 -0700114 bool scale32 = attribute->scale32();
115 bool double_round = attribute->double_round();
116 bool per_channel = attribute->per_channel();
Eric Kunzee5e26762020-10-13 16:11:07 -0700117
Eric Kunzee5e26762020-10-13 16:11:07 -0700118 // reshape [d0, d1, ..., dn] into [d0 * d1 ..., dn]
119 Eigen::array<Eigen::Index, 2> shape_2d;
120 shape_2d[0] = 1;
121 if (Rank > 0)
122 {
123 for (int i = 0; i < Rank - 1; i++)
124 {
125 shape_2d[0] *= this->in->getShape()[i];
126 }
127 shape_2d[1] = this->in->getShape()[Rank - 1];
128 }
129 else
130 {
131 shape_2d[1] = 1;
132 }
133 ETensor2<InEigenType> input_reshaped = this->in->getTensor().reshape(shape_2d);
134
135 ETensor2<OutEigenType> output_2d(shape_2d);
136
Eric Kunzee5e26762020-10-13 16:11:07 -0700137 if (per_channel)
138 {
139 ETensor2<InEigenType> curr_channel_slice_prescaled;
140 ETensor2<OutEigenType> curr_channel_slice_postscaled;
141 int32_t channel_multiplier, channel_shift;
142 Eigen::array<Eigen::Index, 2> begin, size;
143 size = Eigen::array<Eigen::Index, 2>({ shape_2d[0], 1 });
Kevin Chengacb550f2021-06-29 15:32:19 -0700144 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700145 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700146 for (int32_t i = 0; i < shape_2d[1]; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700147 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700148 begin = Eigen::array<Eigen::Index, 2>({ 0, i });
149 curr_channel_slice_prescaled = input_reshaped.slice(begin, size);
150 channel_multiplier = multiplier[i];
151 channel_shift = shift[i];
152 curr_channel_slice_postscaled =
153 curr_channel_slice_prescaled.unaryExpr([input_zp, output_zp, channel_multiplier, channel_shift,
154 double_round, scale32](InEigenType in_val) -> OutEigenType {
155 InEigenType input_zp_shifted = in_val - (InEigenType)input_zp;
156 int32_t scaled;
157 if (scale32)
158 scaled = TosaReference::QuantUtil::apply_scale_32(input_zp_shifted, channel_multiplier,
159 channel_shift, double_round);
160 else
161 scaled = TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, channel_multiplier,
162 channel_shift);
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000163 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp;
164 int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
165 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
166 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
167 {
168 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" + std::to_string(output_zp) + "] not in i32 range";
169 throw desc;
170 }
171 OutEigenType out_val = static_cast<OutEigenType>(res_in_64);
Kevin Chengacb550f2021-06-29 15:32:19 -0700172 out_val = std::max<OutEigenType>(out_val, QMin);
173 out_val = std::min<OutEigenType>(out_val, QMax);
174 return out_val;
175 });
176
177 for (int32_t j = 0; j < shape_2d[0]; j++)
178 {
179 output_2d(j, i) = curr_channel_slice_postscaled(j, 0);
180 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700181 }
182 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700183 catch (std::string desc)
184 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000185 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700186 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700187 }
188 else
189 {
190 int32_t tensor_multiplier = multiplier[0];
191 int32_t tensor_shift = shift[0];
Kevin Chengacb550f2021-06-29 15:32:19 -0700192 try
193 {
194 output_2d = input_reshaped.unaryExpr([input_zp, output_zp, tensor_multiplier, tensor_shift, double_round,
195 scale32](InEigenType in_val) -> OutEigenType {
196 InEigenType input_zp_shifted = in_val - (InEigenType)input_zp;
197 int32_t scaled;
198 if (scale32)
199 scaled = TosaReference::QuantUtil::apply_scale_32(input_zp_shifted, tensor_multiplier, tensor_shift,
200 double_round);
201 else
202 scaled =
203 TosaReference::QuantUtil::apply_scale_16(input_zp_shifted, tensor_multiplier, tensor_shift);
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000204 int64_t res_in_64 = static_cast<int64_t>(scaled) + output_zp;
205 int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
206 int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
207 if (res_in_64 > i32_max_in_64 || res_in_64 < i32_min_in_64)
208 {
209 std::string desc = "scaling result [" + std::to_string(scaled) + "] plus output_zp [" + std::to_string(output_zp) + "] not in i32 range";
210 throw desc;
211 }
212
213 OutEigenType out_val = static_cast<OutEigenType>(res_in_64);
Kevin Chengacb550f2021-06-29 15:32:19 -0700214 out_val = std::max<OutEigenType>(out_val, QMin);
215 out_val = std::min<OutEigenType>(out_val, QMax);
216 return out_val;
217 });
218 }
219 catch (std::string desc)
220 {
Jeremy Johnsondf628d42023-01-10 14:40:54 +0000221 REQUIRE(false, "OpRescale failure: %s.", desc.c_str());
Kevin Chengacb550f2021-06-29 15:32:19 -0700222 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700223 }
224
225 // reshape [d0 * d1 ..., dn] back to [d0, d1, ..., dn]
226 Eigen::array<Eigen::Index, Rank> output_shape;
227 for (int i = 0; i < Rank; i++)
228 {
229 output_shape[i] = this->out->getShape()[i];
230 }
231 this->out->getTensor() = output_2d.reshape(output_shape);
232
233 return GraphNode::eval();
234}
235
236template <int Rank, DType InDtype, DType OutDtype>
Kevin Chengacb550f2021-06-29 15:32:19 -0700237OpCast<Rank, InDtype, OutDtype>::OpCast(SubgraphTraverser* sgt_,
238 TosaAttributeBase* attribute_,
Kevin Chengacb550f2021-06-29 15:32:19 -0700239 uint64_t id_)
240 : GraphNode(sgt_, Op_CAST, id_)
Eric Kunzee5e26762020-10-13 16:11:07 -0700241{
242 setRequiredOperands(1, 1);
243 setRequiredRank(0, 6);
244}
245
246template <int Rank, DType InDtype, DType OutDtype>
247OpCast<Rank, InDtype, OutDtype>::~OpCast()
248{}
249
250template <int Rank, DType InDtype, DType OutDtype>
251int OpCast<Rank, InDtype, OutDtype>::checkTensorAttributes()
252{
253 if (validateRequiredOperands())
254 return 1;
255
256 if (validateRequiredRank(inputs[0]) || validateRequiredRank(outputs[0]))
257 {
258 return 1;
259 }
260
261 // output and input must be the same rank and size
262 if (inputs[0]->matchRankSize(*outputs[0]))
263 {
264 printNodeValidationError("OpCast: input and output rank/size must match");
265 return 1;
266 }
267
268 in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
269 out = dynamic_cast<TosaReference::TensorTemplate<TOut>*>(outputs[0]);
270
271 ASSERT_MEM(in && out);
272
273 return 0;
274}
275
276template <int Rank, DType InDtype, DType OutDtype>
277int OpCast<Rank, InDtype, OutDtype>::eval()
278{
279 this->out->getTensor() = this->in->getTensor().unaryExpr(cast_helper.get_fcn());
280
281 return GraphNode::eval();
282}
283
284template <DType InDtype, DType OutDtype>
285CastHelper<InDtype, OutDtype>::CastHelper()
286{
287 fcn = [](InEigenType in) -> OutEigenType {
288 OutEigenType out = (OutEigenType)in; // implicit sign_extend() if sizeof(out_t) >= sizeof(in_t)
Eric Kunzee5e26762020-10-13 16:11:07 -0700289 return out;
290 };
291}
292
293template <DType InDtype>
294CastHelper<InDtype, DType_BOOL>::CastHelper()
295{
296 fcn = [](InEigenType in) -> bool { return (in != 0) ? true : false; };
297}
298
299template <DType OutDtype>
300CastHelper<DType_BOOL, OutDtype>::CastHelper()
301{
302 fcn = [](bool in) -> OutEigenType {
303 OutEigenType out = in ? (OutEigenType)1 : (OutEigenType)0;
304 return out;
305 };
306}
307
308template <DType InDtype>
James Ward8b390432022-08-12 20:48:56 +0100309CastHelper<InDtype, DType_FP16>::CastHelper()
310{
James Ward736fd1a2023-01-23 17:13:37 +0000311 // Integer data converted to fp16 (stored as fp32)
James Ward8b390432022-08-12 20:48:56 +0100312 fcn = [](InEigenType in) -> float {
James Ward736fd1a2023-01-23 17:13:37 +0000313 half_float::half h = half_float::half(in);
314 float out = half_float::half_cast<float, half_float::half>(h);
315 return out;
316 };
317}
318
319CastHelper<DType_FP32, DType_FP16>::CastHelper()
320{
321 // fp32 data converted to fp16 (stored as fp32)
322 fcn = [](float in) -> float {
323 float out = fpTrunc<DType_FP16>(in); // truncate required for conversion from higher precision
324 return out;
325 };
326}
327
328template <DType InDtype>
329CastHelper<InDtype, DType_BF16>::CastHelper()
330{
331 // Integer data converted to bf16 (stored as fp32)
332 fcn = [](InEigenType in) -> float {
333 float out = (float)in; // default cast to float is round_to_nearest_float()
334 return out;
335 };
336}
337
338CastHelper<DType_FP32, DType_BF16>::CastHelper()
339{
340 // fp32 data converted to bf16 (stored as fp32)
341 fcn = [](float in) -> float {
342 return fpTrunc<DType_BF16>(in); // truncate required for conversions from higher precision
James Ward8b390432022-08-12 20:48:56 +0100343 };
344}
345
346template <DType OutDtype>
347CastHelper<DType_FP16, OutDtype>::CastHelper()
348{
James Ward736fd1a2023-01-23 17:13:37 +0000349 // fp16 data (stored as fp32) converted to integer
James Ward8b390432022-08-12 20:48:56 +0100350 fcn = [](float in) -> OutEigenType {
James Ward736fd1a2023-01-23 17:13:37 +0000351 // Cast from float representation back to half_float before rounding
352 half_float::half h = half_float::half(in);
Eric Kunze57bc0792023-01-25 10:05:51 -0800353 h = std::rint(h);
James Ward736fd1a2023-01-23 17:13:37 +0000354 OutEigenType out = half_float::half_cast<OutEigenType, half_float::half>(h);
James Ward8b390432022-08-12 20:48:56 +0100355 out = std::max<OutEigenType>(out, OutMin);
356 out = std::min<OutEigenType>(out, OutMax);
357 return out;
358 };
359}
360
James Ward736fd1a2023-01-23 17:13:37 +0000361CastHelper<DType_FP16, DType_FP32>::CastHelper()
362{
363 // No-op since fp16 values treated internally as their fp32 representation
364 fcn = [](float in) -> OutEigenType {
365 return in;
366 };
367}
368
369template <DType OutDtype>
370CastHelper<DType_BF16, OutDtype>::CastHelper()
371{
372 // bf16 data (stored as fp32) converted to integer
373 fcn = [](float in) -> OutEigenType {
374 OutEigenType out = std::round(in);
375 out = std::max<OutEigenType>(out, OutMin);
376 out = std::min<OutEigenType>(out, OutMax);
377 return out;
378 };
379}
380
381CastHelper<DType_BF16, DType_FP32>::CastHelper()
382{
383 // No-op since bf16 values treated as truncated fp32 internally
384 fcn = [](InEigenType in) -> OutEigenType {
385 return in;
386 };
387}
388
James Ward8b390432022-08-12 20:48:56 +0100389template <DType InDtype>
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100390CastHelper<InDtype, DType_FP32>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700391{
James Ward736fd1a2023-01-23 17:13:37 +0000392 // Integer data converted to fp32
Eric Kunzee5e26762020-10-13 16:11:07 -0700393 fcn = [](InEigenType in) -> float {
394 float out = (OutEigenType)in; // default cast to float is round_to_nearest_float()
395 return out;
396 };
397}
398
399template <DType OutDtype>
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100400CastHelper<DType_FP32, OutDtype>::CastHelper()
Eric Kunzee5e26762020-10-13 16:11:07 -0700401{
James Ward736fd1a2023-01-23 17:13:37 +0000402 // fp32 data converted to integer
Eric Kunzee5e26762020-10-13 16:11:07 -0700403 fcn = [](float in) -> OutEigenType {
Eric Kunze57bc0792023-01-25 10:05:51 -0800404 OutEigenType out = std::rint(in);
Eric Kunzee5e26762020-10-13 16:11:07 -0700405 out = std::max<OutEigenType>(out, OutMin);
406 out = std::min<OutEigenType>(out, OutMax);
407 return out;
408 };
409}
410
411// template explicit instantiation
412DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT8);
413DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT16);
414DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BOOL, INT32);
415DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BOOL);
416DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT16);
417DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, INT32);
James Ward8b390432022-08-12 20:48:56 +0100418DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000419DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100420DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT8, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700421DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BOOL);
422DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT8);
423DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, INT32);
James Ward8b390432022-08-12 20:48:56 +0100424DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000425DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100426DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT16, FP32);
Eric Kunzee5e26762020-10-13 16:11:07 -0700427DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BOOL);
428DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT8);
429DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, INT16);
James Ward8b390432022-08-12 20:48:56 +0100430DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP16);
James Ward736fd1a2023-01-23 17:13:37 +0000431DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, BF16);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100432DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, INT32, FP32);
James Ward8b390432022-08-12 20:48:56 +0100433DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT8);
434DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT16);
435DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000436DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP16, FP32);
James Ward24dbc422022-10-19 12:20:31 +0100437DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT8);
438DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT16);
439DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000440DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, BF16, FP32);
Jeremy Johnsonbc2a3db2022-09-27 13:50:00 +0100441DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT8);
442DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT16);
443DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, INT32);
James Ward736fd1a2023-01-23 17:13:37 +0000444DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, FP16);
445DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpCast, FP32, BF16);
Eric Kunzee5e26762020-10-13 16:11:07 -0700446
Kevin Cheng3a478572021-01-22 17:21:02 -0800447DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT8);
448DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT16);
449DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, INT32);
450DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700451DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT16);
452DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800453DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700454DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT16);
455DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT32, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800456DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT8);
Eric Kunzee5e26762020-10-13 16:11:07 -0700457DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT16);
458DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT48, INT32);
Kevin Cheng3a478572021-01-22 17:21:02 -0800459DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100460DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT8, INT16);
461DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, UINT16, INT16);
Kevin Cheng3a478572021-01-22 17:21:02 -0800462DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT8, UINT8);
Jeremy Johnsonf7f78ae2022-05-25 15:26:38 +0100463DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT8);
464DEF_INSTANTIATE_RANK0_6_ONE_RANK_TWO_TYPE(OpRescale, INT16, UINT16);