| 63 | } |
| 64 | |
| 65 | TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, |
| 66 | TfLiteConvParams* params, int width, int height, |
| 67 | int filter_width, int filter_height, int out_width, |
| 68 | int out_height, const TfLiteType data_type, |
| 69 | OpData* data) { |
| 70 | data->padding.height = |
| 71 | ComputePadding(params->stride_height, params->dilation_height_factor, |
| 72 | height, filter_height, out_height); |
| 73 | data->padding.width = |
| 74 | ComputePadding(params->stride_width, params->dilation_width_factor, width, |
| 75 | filter_width, out_width); |
| 76 | |
| 77 | // Note that quantized inference requires that all tensors have their |
| 78 | // parameters set. This is usually done during quantized training. |
| 79 | if (data_type != kTfLiteFloat32) { |
| 80 | const TfLiteTensor* input = GetInput(context, node, kInputTensor); |
| 81 | const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); |
| 82 | const TfLiteTensor* bias = |
| 83 | GetOptionalInputTensor(context, node, kBiasTensor); |
| 84 | TfLiteTensor* output = GetOutput(context, node, kOutputTensor); |
| 85 | |
| 86 | double real_multiplier = 0.0; |
| 87 | TF_LITE_ENSURE_STATUS(GetQuantizedConvolutionMultipler( |
| 88 | context, input, filter, bias, output, &real_multiplier)); |
| 89 | int exponent; |
| 90 | QuantizeMultiplier(real_multiplier, &data->output_multiplier, &exponent); |
| 91 | data->output_shift = -exponent; |
| 92 | |
| 93 | CalculateActivationRangeQuantized(context, params->activation, output, |
| 94 | &data->output_activation_min, |
| 95 | &data->output_activation_max); |
| 96 | } |
| 97 | return kTfLiteOk; |
| 98 | } |
| 99 | |
| 100 | void* Init(TfLiteContext* context, const char* buffer, size_t length) { |
| 101 | return nullptr; |
no test coverage detected