| 2111 | } |
| 2112 | |
| 2113 | inline void FakeQuant(const tflite::FakeQuantParams& op_params, |
| 2114 | const RuntimeShape& input_shape, const float* input_data, |
| 2115 | const RuntimeShape& output_shape, float* output_data) { |
| 2116 | gemmlowp::ScopedProfilingLabel label("FakeQuant"); |
| 2117 | float rmin = op_params.minmax.min; |
| 2118 | float rmax = op_params.minmax.max; |
| 2119 | int num_bits = op_params.num_bits; |
| 2120 | // 0 should always be a representable value. Let's assume that the initial |
| 2121 | // min,max range contains 0. |
| 2122 | TFLITE_DCHECK_LE(rmin, 0.0f); |
| 2123 | TFLITE_DCHECK_GE(rmax, 0.0f); |
| 2124 | TFLITE_DCHECK_LT(rmin, rmax); |
| 2125 | |
| 2126 | // Code matches tensorflow's FakeQuantWithMinMaxArgsFunctor. |
| 2127 | int quant_min = 0; |
| 2128 | int quant_max = (1 << num_bits) - 1; |
| 2129 | float nudged_min, nudged_max, nudged_scale; |
| 2130 | NudgeQuantizationRange(rmin, rmax, quant_min, quant_max, &nudged_min, |
| 2131 | &nudged_max, &nudged_scale); |
| 2132 | const int flat_size = MatchingFlatSize(input_shape, output_shape); |
| 2133 | FakeQuantizeArray(nudged_scale, nudged_min, nudged_max, input_data, |
| 2134 | output_data, flat_size); |
| 2135 | } |
| 2136 | |
| 2137 | template <typename SrcT, typename DstT> |
| 2138 | inline void Cast(const RuntimeShape& input_shape, const SrcT* input_data, |
no test coverage detected