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

Function QuantizeOpOutput

tensorflow/lite/tools/optimize/quantize_model.cc:451–545  ·  view source on GitHub ↗

Quantize the op output.

Source from the content-addressed store, hash-verified

449
450// Quantize the op output.
451TfLiteStatus QuantizeOpOutput(
452 ModelT* model, int32_t subgraph_idx, int32_t op_idx,
453 operator_property::OperatorProperty property,
454 const std::pair<int32_t, operator_property::TensorProperty>& output,
455 ErrorReporter* error_reporter) {
456 int32_t output_idx = output.first;
457 operator_property::TensorProperty tensor_property = output.second;
458 // If the operator is not quantizable, we don't need to do anything for the
459 // output.
460 if (!property.quantizable) {
461 return kTfLiteOk;
462 }
463 SubGraphT* subgraph = model->subgraphs.at(subgraph_idx).get();
464 OperatorT* op = subgraph->operators[op_idx].get();
465 const BuiltinOperator op_code =
466 model->operator_codes[op->opcode_index]->builtin_code;
467 if (output_idx >= op->outputs.size()) {
468 error_reporter->Report(
469 "Required output index %d is larger than the output length of "
470 "op %s at index %d in subgraph %d",
471 output_idx, op->outputs.size(), EnumNameBuiltinOperator(op_code),
472 op_idx, subgraph_idx);
473 return kTfLiteError;
474 }
475
476 TensorT* output_tensor = subgraph->tensors[op->outputs[output_idx]].get();
477 if (ShouldRestrictSameInputOutputScale(property)) {
478 // Copy quantization parameter. For average pool, max pool, etc
479 // min/max can be different but we want them to be the same.
480 // Get scale and zero point of input.
481 if (property.inputs[0].first >= op->inputs.size()) {
482 error_reporter->Report(
483 "Required input index %d is larger than the input length of "
484 "op %s at index %d in subgraph %d",
485 property.inputs[0].first, op->inputs.size(),
486 EnumNameBuiltinOperator(op_code), op_idx, subgraph_idx);
487 return kTfLiteError;
488 }
489 const int input_tensor_idx = op->inputs[property.inputs[0].first];
490 TensorT* input_tensor = subgraph->tensors[input_tensor_idx].get();
491 if (input_tensor->quantization->scale.size() != 1 ||
492 input_tensor->quantization->zero_point.size() != 1 ||
493 input_tensor->quantization->min.size() != 1 ||
494 input_tensor->quantization->max.size() != 1) {
495 error_reporter->Report(
496 "Invalid quantization params for op %s at index %d "
497 "in subgraph %d",
498 EnumNameBuiltinOperator(op_code), op_idx, subgraph_idx);
499 return kTfLiteError;
500 }
501
502 const float input_scale = input_tensor->quantization->scale[0];
503 const int32_t input_zero_point = input_tensor->quantization->zero_point[0];
504
505 const float min = input_tensor->quantization->min[0];
506 const float max = input_tensor->quantization->max[0];
507 if (utils::HasMinMax(output_tensor)) {
508 if (output_tensor->quantization->min[0] != min ||

Callers 1

Calls 9

EnumNameBuiltinOperatorFunction · 0.85
HasMinMaxFunction · 0.85
QuantizeActivationFunction · 0.85
getMethod · 0.45
atMethod · 0.45
sizeMethod · 0.45
ReportMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected