예제 #1
0
 def __add__(self, other):
     if isinstance(other,
                   QuantTensor) and self.is_not_none and other.is_not_none:
         self.check_scaling_factors_same(other)
         self.check_zero_points_same(other)
         output_value = self.value + other.value
         output_scale = (self.scale + other.scale) / 2
         output_zero_point = (self.zero_point + other.zero_point) / 2
         max_val = max_int(signed=self.signed,
                           narrow_range=False,
                           bit_width=self.bit_width)
         max_val += max_int(signed=other.signed,
                            narrow_range=False,
                            bit_width=other.bit_width)
         min_val = min_int(signed=self.signed,
                           narrow_range=False,
                           bit_width=self.bit_width)
         min_val += min_int(signed=other.signed,
                            narrow_range=False,
                            bit_width=other.bit_width)
         output_bit_width = ceil_ste(torch.log2(max_val - min_val))
         output_signed = self.signed or other.signed
         output_training = self.training or other.training
         output = QuantTensor(value=output_value,
                              scale=output_scale,
                              zero_point=output_zero_point,
                              bit_width=output_bit_width,
                              signed=output_signed,
                              training=output_training)
     elif isinstance(other, QuantTensor):
         output = QuantTensor(self.value + other.value)
     else:
         output = QuantTensor(self.value + other)
     return output
예제 #2
0
def test_IntQuant(x, narrow_range, signed, bit_width, scale, int_scale,
                  float_to_int_impl, scale_multiplier):
    float_to_int_impl_mock = Mock()
    tensor_clamp_impl = TensorClamp()

    value = torch.tensor(x)
    bit_width = torch.tensor(bit_width, dtype=torch.float)
    scale = torch.tensor(scale)
    int_scale = torch.tensor(int_scale)

    tol = scale * scale_multiplier
    float_to_int_impl_mock.side_effect = float_to_int_impl()

    obj = IntQuant(narrow_range=narrow_range,
                   signed=signed,
                   float_to_int_impl=float_to_int_impl_mock,
                   tensor_clamp_impl=tensor_clamp_impl)
    output = obj(scale, int_scale, bit_width, value)

    min_value = int(min_int(signed, narrow_range, bit_width))
    max_value = int(max_int(signed, bit_width))
    admissible_values = [x for x in range(min_value, max_value + 1)]

    value = (value / scale) * int_scale
    expected_output = tensor_clamp(value,
                                   min_val=min_int(signed, narrow_range,
                                                   bit_width),
                                   max_val=max_int(signed, bit_width))
    expected_output = (expected_output / int_scale) * scale

    int_output = obj.to_int(scale, int_scale, bit_width, value)

    # The assert is performed internally check_admissible_values
    check_admissible_values(int_output, admissible_values)
    assert torch.allclose(expected_output, output, RTOL, tol)
예제 #3
0
 def min_int(self, bit_width):
     return min_int(self.signed, self.narrow_range, bit_width)
예제 #4
0
 def forward(self, bit_width):
     if self.signed:
         return - min_int(self.signed, self.narrow_range, bit_width)
     else:
         return max_int(self.signed, bit_width)
예제 #5
0
 def forward(self, bit_width):
     return -min_int(self.signed, self.narrow_range, bit_width)