| 312 | |
| 313 | template <typename QuantizedType> |
| 314 | void TestQuantizedHardSwish(TensorType tensor_type, int size, float input_min, |
| 315 | float input_max, float output_min, float output_max, |
| 316 | std::minstd_rand* random_engine) { |
| 317 | std::vector<float> float_input_values; |
| 318 | GenerateUniformRandomVector(size, input_min, input_max, random_engine, |
| 319 | &float_input_values); |
| 320 | std::vector<float> float_ref_output_values; |
| 321 | EvalTestReferenceHardSwish(size, float_input_values, |
| 322 | &float_ref_output_values); |
| 323 | for (float& val : float_ref_output_values) { |
| 324 | val = std::min(output_max, std::max(output_min, val)); |
| 325 | } |
| 326 | QuantizedActivationsOpModel m( |
| 327 | BuiltinOperator_HARD_SWISH, |
| 328 | /*input=*/{tensor_type, {1, 1, 1, size}, input_min, input_max}, |
| 329 | /*output=*/{tensor_type, {1, 1, 1, size}, output_min, output_max}); |
| 330 | m.SetInput<QuantizedType>(float_input_values); |
| 331 | |
| 332 | m.Invoke(); |
| 333 | const std::vector<float>& dequantized_output = |
| 334 | m.GetDequantizedOutput<QuantizedType>(); |
| 335 | // The numerical error for any 8bit quantized function is at least one half |
| 336 | // times the quantization step: 0.5 * (kOutMax - kOutMin) / 256. |
| 337 | // To that we add again the quantization step (kOutMax - kOutMin) / 256 |
| 338 | // to allow for an off-by-one rounding error. |
| 339 | const float kTolerance = |
| 340 | std::max(input_max - input_min, output_max - output_min) * (1.5f / 256.f); |
| 341 | EXPECT_THAT(dequantized_output, ElementsAreArray(ArrayFloatNear( |
| 342 | float_ref_output_values, kTolerance))); |
| 343 | } |
| 344 | |
| 345 | template <typename QuantizedType> |
| 346 | void TestQuantizedHardSwishBias(TensorType tensor_type, float input_min, |
nothing calls this directly
no test coverage detected