| 37 | namespace { |
| 38 | |
| 39 | TfLiteStatus QuantizeBias(ModelT* model, const TensorT* input_tensor, |
| 40 | const TensorT* weight_tensor, TensorT* bias_tensor, |
| 41 | bool is_per_channel, int channel_dim_index, |
| 42 | ErrorReporter* error_reporter) { |
| 43 | if (bias_tensor->shape.size() != 1) { |
| 44 | error_reporter->Report("Expected bias tensor shape to be 1."); |
| 45 | return kTfLiteError; |
| 46 | } |
| 47 | |
| 48 | int32_t channel_dim_size = bias_tensor->shape[0]; |
| 49 | TF_LITE_ENSURE(error_reporter, weight_tensor->quantization); |
| 50 | std::vector<float> weight_scales = weight_tensor->quantization->scale; |
| 51 | |
| 52 | if (is_per_channel) { |
| 53 | if (bias_tensor->shape[0] != weight_tensor->shape[channel_dim_index]) { |
| 54 | error_reporter->Report( |
| 55 | "Channel mismatch between bias and weight tensors %d vs %d", |
| 56 | bias_tensor->shape[0], weight_tensor->shape[channel_dim_index]); |
| 57 | return kTfLiteError; |
| 58 | } |
| 59 | if (!input_tensor->quantization || |
| 60 | input_tensor->quantization->scale.size() != 1) { |
| 61 | error_reporter->Report("Input tensor missing quantization information"); |
| 62 | return kTfLiteError; |
| 63 | } |
| 64 | |
| 65 | if (weight_scales.size() != channel_dim_size) { |
| 66 | error_reporter->Report("Mismatch weight scale dimension: %d", |
| 67 | weight_scales.size()); |
| 68 | return kTfLiteError; |
| 69 | } |
| 70 | return utils::SymmetricPerChannelBiasQuantize( |
| 71 | model, bias_tensor, input_tensor->quantization->scale[0], |
| 72 | weight_scales.data(), channel_dim_size); |
| 73 | } else { |
| 74 | if (weight_scales.size() != 1) { |
| 75 | error_reporter->Report( |
| 76 | "Expected per-layer weight scale dimension size 1, got %d", |
| 77 | weight_scales.size()); |
| 78 | return kTfLiteError; |
| 79 | } |
| 80 | return utils::SymmetricPerLayerBiasQuantize( |
| 81 | model, bias_tensor, input_tensor->quantization->scale[0], |
| 82 | weight_scales[0]); |
| 83 | } |
| 84 | return kTfLiteError; |
| 85 | } |
| 86 | |
| 87 | // True if the tensor type has to be modified. |
| 88 | bool TensorTypeChangeRequired(const TensorT* tensor, const TensorType& type) { |
no test coverage detected