| 224 | |
| 225 | template <KernelType kernel_type> |
| 226 | TfLiteStatus EvalAddQuantized(TfLiteContext* context, TfLiteNode* node, |
| 227 | TfLiteAddParams* params, const OpData* data, |
| 228 | const TfLiteTensor* input1, |
| 229 | const TfLiteTensor* input2, |
| 230 | TfLiteTensor* output) { |
| 231 | if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { |
| 232 | tflite::ArithmeticParams op_params; |
| 233 | op_params.left_shift = data->left_shift; |
| 234 | op_params.input1_offset = data->input1_offset; |
| 235 | op_params.input1_multiplier = data->input1_multiplier; |
| 236 | op_params.input1_shift = data->input1_shift; |
| 237 | op_params.input2_offset = data->input2_offset; |
| 238 | op_params.input2_multiplier = data->input2_multiplier; |
| 239 | op_params.input2_shift = data->input2_shift; |
| 240 | op_params.output_offset = data->output_offset; |
| 241 | op_params.output_multiplier = data->output_multiplier; |
| 242 | op_params.output_shift = data->output_shift; |
| 243 | SetActivationParams(data->output_activation_min, |
| 244 | data->output_activation_max, &op_params); |
| 245 | bool need_broadcast = optimized_ops::ProcessBroadcastShapes( |
| 246 | GetTensorShape(input1), GetTensorShape(input2), &op_params); |
| 247 | #define TF_LITE_ADD(type, opname, dtype) \ |
| 248 | type::opname(op_params, GetTensorShape(input1), \ |
| 249 | GetTensorData<dtype>(input1), GetTensorShape(input2), \ |
| 250 | GetTensorData<dtype>(input2), GetTensorShape(output), \ |
| 251 | GetTensorData<dtype>(output)); |
| 252 | if (output->type == kTfLiteInt8) { |
| 253 | if (kernel_type == kReference) { |
| 254 | if (need_broadcast) { |
| 255 | TF_LITE_ADD(reference_integer_ops, BroadcastAdd4DSlow, int8_t); |
| 256 | } else { |
| 257 | TF_LITE_ADD(reference_integer_ops, Add, int8_t); |
| 258 | } |
| 259 | } else { |
| 260 | if (op_params.broadcast_category == |
| 261 | BroadcastableOpCategory::kGenericBroadcast) { |
| 262 | TF_LITE_ADD(reference_integer_ops, BroadcastAdd4DSlow, int8_t); |
| 263 | } else if (need_broadcast) { |
| 264 | TF_LITE_ADD(optimized_integer_ops, BroadcastAddFivefold, int8_t); |
| 265 | } else { |
| 266 | TF_LITE_ADD(optimized_integer_ops, Add, int8_t); |
| 267 | } |
| 268 | } |
| 269 | } else { |
| 270 | if (kernel_type == kReference) { |
| 271 | if (need_broadcast) { |
| 272 | TF_LITE_ADD(reference_ops, BroadcastAdd4DSlow, uint8_t); |
| 273 | } else { |
| 274 | TF_LITE_ADD(reference_ops, Add, uint8_t); |
| 275 | } |
| 276 | } else { |
| 277 | if (op_params.broadcast_category == |
| 278 | BroadcastableOpCategory::kGenericBroadcast) { |
| 279 | TF_LITE_ADD(optimized_ops, BroadcastAdd4DSlow, uint8_t); |
| 280 | } else if (need_broadcast) { |
| 281 | TF_LITE_ADD(optimized_ops, BroadcastAddFivefold, uint8_t); |
| 282 | } else { |
| 283 | TF_LITE_ADD(optimized_ops, Add, uint8_t); |
nothing calls this directly
no test coverage detected