MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / QuantizationParams

Method QuantizationParams

tensorflow/lite/kernels/test_util.h:375–443  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

373 private:
374 template <typename T>
375 std::pair<float, int32_t> QuantizationParams(float f_min, float f_max) {
376 int32_t zero_point = 0;
377 float scale = 0;
378 const T qmin = std::numeric_limits<T>::min();
379 const T qmax = std::numeric_limits<T>::max();
380 const float qmin_double = qmin;
381 const float qmax_double = qmax;
382 // 0 should always be a representable value. Let's assume that the initial
383 // min,max range contains 0.
384 CHECK_LE(f_min, 0);
385 CHECK_GE(f_max, 0);
386 if (f_min == f_max) {
387 // Special case where the min,max range is a point. Should be {0}.
388 CHECK_EQ(f_min, 0);
389 CHECK_EQ(f_max, 0);
390 return {scale, zero_point};
391 }
392
393 // General case.
394 //
395 // First determine the scale.
396 scale = (f_max - f_min) / (qmax_double - qmin_double);
397
398 // Zero-point computation.
399 // First the initial floating-point computation. The zero-point can be
400 // determined from solving an affine equation for any known pair
401 // (real value, corresponding quantized value).
402 // We know two such pairs: (rmin, qmin) and (rmax, qmax).
403 // The arithmetic error on the zero point computed from either pair
404 // will be roughly machine_epsilon * (sum of absolute values of terms)
405 // so we want to use the variant that adds the smaller terms.
406 const float zero_point_from_min = qmin_double - f_min / scale;
407 const float zero_point_from_max = qmax_double - f_max / scale;
408
409 const float zero_point_from_min_error =
410 std::abs(qmin_double) + std::abs(f_min / scale);
411
412 const float zero_point_from_max_error =
413 std::abs(qmax_double) + std::abs(f_max / scale);
414
415 const float zero_point_double =
416 zero_point_from_min_error < zero_point_from_max_error
417 ? zero_point_from_min
418 : zero_point_from_max;
419
420 // Now we need to nudge the zero point to be an integer
421 // (our zero points are integer, and this is motivated by the requirement
422 // to be able to represent the real value "0" exactly as a quantized value,
423 // which is required in multiple places, for example in Im2col with SAME
424 // padding).
425
426 T nudged_zero_point = 0;
427 if (zero_point_double < qmin_double) {
428 nudged_zero_point = qmin;
429 } else if (zero_point_double > qmax_double) {
430 nudged_zero_point = qmax;
431 } else {
432 nudged_zero_point = static_cast<T>(std::round(zero_point_double));

Callers

nothing calls this directly

Calls 4

minFunction · 0.50
maxFunction · 0.50
absFunction · 0.50
roundFunction · 0.50

Tested by

no test coverage detected