diff --git a/mace/kernels/concat.h b/mace/kernels/concat.h index 696d4ff034c852ff9fdfd2f38b0682fc8b2dfe50..7cd6958fca52d3a5e9bb237d9db8ac2b0aa7d87c 100644 --- a/mace/kernels/concat.h +++ b/mace/kernels/concat.h @@ -44,8 +44,8 @@ struct ConcatFunctor : ConcatFunctorBase { : ConcatFunctorBase(context, axis) {} MaceStatus operator()(const std::vector &input_list, - Tensor *output, - StatsFuture *future) { + Tensor *output, + StatsFuture *future) { MACE_UNUSED(future); const Tensor *input0 = input_list.front(); const size_t inputs_count = input_list.size(); @@ -59,6 +59,9 @@ struct ConcatFunctor : ConcatFunctorBase { outer_sizes[0] = input0->size() / inner_size; for (size_t i = 1; i < inputs_count; ++i) { const Tensor *input = input_list[i]; + MACE_CHECK(input->scale() == output->scale() + && input->zero_point() == output->zero_point(), + "Inputs and output must have the same scale and zero_point."); MACE_CHECK(input->dim_size() == input0->dim_size(), "Ranks of all input tensors must be same."); for (int j = 0; j < input->dim_size(); ++j) { diff --git a/mace/kernels/resize_bilinear.h b/mace/kernels/resize_bilinear.h index 4fab243ab16de40c0e6c13595c1e7c05944667ca..b4ed109a45b3010bc60f4ad873243a4a52e85514 100644 --- a/mace/kernels/resize_bilinear.h +++ b/mace/kernels/resize_bilinear.h @@ -22,6 +22,7 @@ #include "mace/core/future.h" #include "mace/core/tensor.h" #include "mace/kernels/kernel.h" +#include "mace/utils/quantize.h" #ifdef MACE_ENABLE_OPENCL #include "mace/core/runtime/opencl/cl2_header.h" @@ -90,7 +91,7 @@ inline uint8_t ComputeLerp(const uint8_t top_left, const float y_lerp) { const float top = top_left + (top_right - top_left) * x_lerp; const float bottom = bottom_left + (bottom_right - bottom_left) * x_lerp; - return static_cast(roundf(top + (bottom - top) * y_lerp)); + return Saturate(roundf(top + (bottom - top) * y_lerp)); } template diff --git a/mace/python/tools/converter_tool/transformer.py b/mace/python/tools/converter_tool/transformer.py index 787697cbe3249c2e3334b414f2d64e8ca717b9c6..5760c76fbca15d3f898983525d499accaac94814 100644 --- a/mace/python/tools/converter_tool/transformer.py +++ b/mace/python/tools/converter_tool/transformer.py @@ -1674,10 +1674,12 @@ class Transformer(base_converter.ConverterInterface): """Assume biasadd has been already folded with convolution and fc""" if tensor.data_type == mace_pb2.DT_FLOAT: ops = self._consumers.get(tensor.name, None) - if len(ops) == 1 and ops[0].type in [MaceOp.Conv2D.name, - MaceOp.Deconv2D.name, - MaceOp.DepthwiseConv2d.name, - MaceOp.FullyConnected.name] \ + if ops is not None \ + and len(ops) == 1 \ + and ops[0].type in [MaceOp.Conv2D.name, + MaceOp.Deconv2D.name, + MaceOp.DepthwiseConv2d.name, + MaceOp.FullyConnected.name] \ and len(ops[0].input) >= 3 \ and ops[0].input[2] == tensor.name: conv_op = ops[0] @@ -1723,6 +1725,13 @@ class Transformer(base_converter.ConverterInterface): return quantize_info + def copy_quantize_info(self, op, info): + quantize_info = op.quantize_info.add() + quantize_info.minval = info.minval + quantize_info.maxval = info.maxval + quantize_info.scale = info.scale + quantize_info.zero_point = info.zero_point + def transform_fake_quantize(self): if not self._option.quantize: return False @@ -1832,19 +1841,34 @@ class Transformer(base_converter.ConverterInterface): for op in self._model.op: if op.type in [MaceOp.Pooling.name, MaceOp.Squeeze.name, - MaceOp.Concat.name, MaceOp.ResizeBilinear.name, MaceOp.BatchToSpaceND.name, MaceOp.SpaceToBatchND.name]: del op.quantize_info[:] producer_op = self._producer[op.input[0]] - quantize_info = op.quantize_info.add() - quantize_info.minval = producer_op.quantize_info[0].minval - quantize_info.maxval = producer_op.quantize_info[0].maxval - quantize_info.scale = producer_op.quantize_info[0].scale - quantize_info.zero_point = \ - producer_op.quantize_info[0].zero_point + self.copy_quantize_info(op, producer_op.quantize_info[0]) + self._quantize_activation_info[op.output[0]] = \ + op.quantize_info[0] + elif op.type == MaceOp.Concat.name: + if op.quantize_info: + maxval = op.quantize_info[0].maxval + minval = op.quantize_info[0].minval + del op.quantize_info[:] + else: + maxval = float("-inf") + minval = float("inf") + for i in range(len(op.input)): + minval = min(minval, self._producer[op.input[i]].quantize_info[0].minval) # noqa + maxval = max(maxval, self._producer[op.input[i]].quantize_info[0].maxval) # noqa + quantize_info = \ + self.add_quantize_info(op, minval, maxval) self._quantize_activation_info[op.output[0]] = quantize_info + for i in range(len(op.input)): + producer_op = self._producer[op.input[i]] + del producer_op.quantize_info[:] + self.copy_quantize_info(producer_op, quantize_info) + self._quantize_activation_info[producer_op.output[0]] = \ + producer_op.quantize_info[0] elif op.type == MaceOp.Softmax.name: del op.quantize_info[:] quantize_info = \ @@ -1859,16 +1883,12 @@ class Transformer(base_converter.ConverterInterface): del op.quantize_info[:] producer_op0 = self._producer[op.input[0]] producer_op1 = self._producer[op.input[1]] - quantize_info = op.quantize_info.add() - quantize_info.minval = producer_op0.quantize_info[0].minval \ + minval = producer_op0.quantize_info[0].minval \ + producer_op1.quantize_info[0].minval - quantize_info.maxval = producer_op0.quantize_info[0].maxval \ + maxval = producer_op0.quantize_info[0].maxval \ + producer_op1.quantize_info[0].maxval - scale, zero = quantize_util.adjust_range(quantize_info.minval, - quantize_info.maxval, - non_zero=False) - quantize_info.scale = scale - quantize_info.zero_point = zero + quantize_info = \ + self.add_quantize_info(op, minval, maxval) self._quantize_activation_info[op.output[0]] = quantize_info print ("Add default quantize info for input")