Remove obsoleted v0::QuantizedConvolution op (#2958)
This commit is contained in:
@@ -130,7 +130,6 @@ NGRAPH_OP(PriorBox, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(PriorBoxClustered, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(Proposal, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(Quantize, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(QuantizedConvolution, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(QuantizedDot, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(RNNCell, ngraph::op::v0, 0)
|
||||
NGRAPH_OP(ROIPooling, ngraph::op::v0, 0)
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
//*****************************************************************************
|
||||
// Copyright 2017-2020 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//*****************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngraph/coordinate_diff.hpp"
|
||||
#include "ngraph/op/op.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
namespace v0
|
||||
{
|
||||
class NGRAPH_DEPRECATED(
|
||||
"This operation is deprecated and will be removed soon. Please do not use it.")
|
||||
NGRAPH_API QuantizedConvolution : public Op
|
||||
{
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"QuantizedConvolution", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
/// \brief Constructs a quantized convolution operation.
|
||||
///
|
||||
/// \param input The node producing the input data batch tensor.
|
||||
/// \param filters The node producing the filters tensor.
|
||||
/// \param window_movement_strides The window movement strides.
|
||||
/// \param window_dilation_strides The window dilation strides.
|
||||
/// \param padding_below The padding-below sizes.
|
||||
/// \param padding_above The padding-above sizes.
|
||||
/// \param data_dilation_strides The data dilation strides.
|
||||
/// \param input_scale Scale to transform the input
|
||||
/// \param input_zero_point Zero point used for mapping
|
||||
/// \param filter_scale Scale to transform the filters
|
||||
/// \param filter_zero_point Zero point used for mapping
|
||||
/// \param output_scale Scale to transform the output
|
||||
/// \param output_zero_point Zero point used for mapping
|
||||
/// \param output_type Output element type
|
||||
/// \param input_axes Input axes set for channel wise quantization
|
||||
/// \param filter_axes Filter axes set for channel wise quantization
|
||||
/// \param output_axes Output axes set for channel wise quantization
|
||||
QuantizedConvolution(const Output<Node>& input,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const Output<Node>& input_scale,
|
||||
const Output<Node>& input_zero_point,
|
||||
const Output<Node>& filter_scale,
|
||||
const Output<Node>& filter_zero_point,
|
||||
const Output<Node>& output_scale,
|
||||
const Output<Node>& output_zero_point,
|
||||
const ngraph::element::Type& output_type,
|
||||
const ngraph::AxisSet& input_axes = ngraph::AxisSet{},
|
||||
const ngraph::AxisSet& filter_axes = ngraph::AxisSet{},
|
||||
const ngraph::AxisSet& output_axes = ngraph::AxisSet{});
|
||||
|
||||
QuantizedConvolution() = default;
|
||||
|
||||
const Strides& get_window_movement_strides() const
|
||||
{
|
||||
return m_window_movement_strides;
|
||||
}
|
||||
const Strides& get_window_dilation_strides() const
|
||||
{
|
||||
return m_window_dilation_strides;
|
||||
}
|
||||
const CoordinateDiff& get_padding_below() const { return m_padding_below; }
|
||||
const CoordinateDiff& get_padding_above() const { return m_padding_above; }
|
||||
const Strides& get_data_dilation_strides() const { return m_data_dilation_strides; }
|
||||
std::shared_ptr<Node> get_filters() { return input_value(1).get_node_shared_ptr(); }
|
||||
std::shared_ptr<Node> get_data_batch()
|
||||
{
|
||||
return input_value(0).get_node_shared_ptr();
|
||||
}
|
||||
const ngraph::element::Type& get_output_type() const { return m_output_type; }
|
||||
const ngraph::AxisSet& get_input_axes() const { return m_input_axes; }
|
||||
const ngraph::AxisSet& get_filter_axes() const { return m_filter_axes; }
|
||||
const ngraph::AxisSet& get_output_axes() const { return m_output_axes; }
|
||||
void validate_and_infer_types() override;
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
protected:
|
||||
Strides m_window_movement_strides;
|
||||
Strides m_window_dilation_strides;
|
||||
CoordinateDiff m_padding_below;
|
||||
CoordinateDiff m_padding_above;
|
||||
Strides m_data_dilation_strides;
|
||||
ngraph::element::Type m_output_type;
|
||||
ngraph::AxisSet m_input_axes;
|
||||
ngraph::AxisSet m_filter_axes;
|
||||
ngraph::AxisSet m_output_axes;
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
};
|
||||
}
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
using v0::QuantizedConvolution;
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,6 @@
|
||||
#include "ngraph/op/proposal.hpp"
|
||||
#include "ngraph/op/psroi_pooling.hpp"
|
||||
#include "ngraph/op/quantize.hpp"
|
||||
#include "ngraph/op/quantized_convolution.hpp"
|
||||
#include "ngraph/op/quantized_dot.hpp"
|
||||
#include "ngraph/op/range.hpp"
|
||||
#include "ngraph/op/read_value.hpp"
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
//*****************************************************************************
|
||||
// Copyright 2017-2020 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//*****************************************************************************
|
||||
|
||||
#include "quantized_convolution.hpp"
|
||||
#include "ngraph/coordinate_diff.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
constexpr NodeTypeInfo op::QuantizedConvolution::type_info;
|
||||
|
||||
op::QuantizedConvolution::QuantizedConvolution(const Output<Node>& input,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const Output<Node>& input_scale,
|
||||
const Output<Node>& input_zero_point,
|
||||
const Output<Node>& filter_scale,
|
||||
const Output<Node>& filter_zero_point,
|
||||
const Output<Node>& output_scale,
|
||||
const Output<Node>& output_zero_point,
|
||||
const element::Type& output_type,
|
||||
const AxisSet& input_axes,
|
||||
const AxisSet& filter_axes,
|
||||
const AxisSet& output_axes)
|
||||
: Op({input,
|
||||
filters,
|
||||
input_scale,
|
||||
input_zero_point,
|
||||
filter_scale,
|
||||
filter_zero_point,
|
||||
output_scale,
|
||||
output_zero_point})
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_window_dilation_strides(window_dilation_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_data_dilation_strides(data_dilation_strides)
|
||||
, m_output_type(output_type)
|
||||
, m_input_axes(input_axes)
|
||||
, m_filter_axes(filter_axes)
|
||||
, m_output_axes(output_axes)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void op::QuantizedConvolution::validate_and_infer_types()
|
||||
{
|
||||
enum
|
||||
{
|
||||
INPUT,
|
||||
FILTER,
|
||||
INPUT_SCALE,
|
||||
INPUT_ZERO_POINT,
|
||||
FILTER_SCALE,
|
||||
FILTER_ZERO_POINT,
|
||||
OUTPUT_SCALE,
|
||||
OUTPUT_ZERO_POINT
|
||||
};
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this, m_output_type.is_static(), "Output element type must not be dynamic");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
m_output_type.is_quantized(),
|
||||
"Output element type (",
|
||||
m_output_type,
|
||||
") must be a quantized type");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(INPUT).is_quantized(),
|
||||
"Input element type (",
|
||||
get_input_element_type(INPUT),
|
||||
") must be a quantized type");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(FILTER).is_quantized(),
|
||||
"Filter element type (",
|
||||
get_input_element_type(FILTER),
|
||||
") must be a quantized type");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(INPUT_SCALE).is_real() ||
|
||||
get_input_element_type(INPUT_SCALE).is_dynamic() ||
|
||||
get_input_element_type(FILTER_SCALE).is_real() ||
|
||||
get_input_element_type(FILTER_SCALE).is_dynamic() ||
|
||||
get_input_element_type(OUTPUT_SCALE).is_real() ||
|
||||
get_input_element_type(OUTPUT_SCALE).is_dynamic(),
|
||||
"Scale must be a floating point number");
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
get_input_element_type(0).compatible(get_input_element_type(INPUT_ZERO_POINT)),
|
||||
"Input Zero point element type (",
|
||||
get_input_element_type(INPUT_ZERO_POINT),
|
||||
") must match input element type (",
|
||||
get_input_element_type(0),
|
||||
")");
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
get_input_element_type(1).compatible(get_input_element_type(FILTER_ZERO_POINT)),
|
||||
"Filter Zero point element type (",
|
||||
get_input_element_type(FILTER_ZERO_POINT),
|
||||
") must match filter element type (",
|
||||
get_input_element_type(1),
|
||||
")");
|
||||
|
||||
// TODO Remove these checks once we support channelwise and vector of scales
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_partial_shape(2).compatible(PartialShape{}) &&
|
||||
get_input_partial_shape(3).compatible(PartialShape{}),
|
||||
"Input scale and input zero point shape must be same and 1");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_partial_shape(4).compatible(PartialShape{}) &&
|
||||
get_input_partial_shape(5).compatible(PartialShape{}),
|
||||
"Filter scale and filter zero point shape must be same and 1");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_partial_shape(6).compatible(PartialShape{}) &&
|
||||
get_input_partial_shape(7).compatible(PartialShape{}),
|
||||
"Output scale and output zero point shape must be same and 1");
|
||||
|
||||
// AxisSet should be empty till we support channel wise quantization
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
m_input_axes == AxisSet{} && m_filter_axes == AxisSet{} &&
|
||||
m_output_axes == AxisSet{},
|
||||
"Input, filter and output AxisSet should be empty");
|
||||
|
||||
const PartialShape& input_shape = get_input_partial_shape(0);
|
||||
const PartialShape& filters_shape = get_input_partial_shape(1);
|
||||
|
||||
PartialShape result_shape;
|
||||
|
||||
result_shape = infer_convolution_forward(this,
|
||||
input_shape,
|
||||
m_data_dilation_strides,
|
||||
m_padding_below,
|
||||
m_padding_above,
|
||||
filters_shape,
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides);
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
get_output_element_type(0).compatible(get_input_element_type(OUTPUT_ZERO_POINT)),
|
||||
"Output Zero point element type (",
|
||||
get_input_element_type(OUTPUT_ZERO_POINT),
|
||||
") must match output element type (",
|
||||
get_output_element_type(0),
|
||||
")");
|
||||
|
||||
set_output_type(0, m_output_type, result_shape);
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::QuantizedConvolution::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return shared_ptr<Node>(new QuantizedConvolution(new_args.at(0),
|
||||
new_args.at(1),
|
||||
get_window_movement_strides(),
|
||||
get_window_dilation_strides(),
|
||||
get_padding_below(),
|
||||
get_padding_above(),
|
||||
get_data_dilation_strides(),
|
||||
new_args.at(2),
|
||||
new_args.at(3),
|
||||
new_args.at(4),
|
||||
new_args.at(5),
|
||||
new_args.at(6),
|
||||
new_args.at(7),
|
||||
m_output_type,
|
||||
m_input_axes,
|
||||
m_filter_axes,
|
||||
m_output_axes));
|
||||
}
|
||||
@@ -152,7 +152,6 @@ set(SRC
|
||||
type_prop/prelu.cpp
|
||||
type_prop/proposal.cpp
|
||||
type_prop/quantize.cpp
|
||||
type_prop/quantized_convolution.cpp
|
||||
type_prop/quantized_dot.cpp
|
||||
type_prop/range.cpp
|
||||
type_prop/read_value.cpp
|
||||
@@ -317,7 +316,6 @@ set(MULTI_TEST_SRC
|
||||
backend/parameter_as_output.in.cpp
|
||||
backend/power.in.cpp
|
||||
backend/quantize_dequantize.in.cpp
|
||||
backend/quantized_convolution.in.cpp
|
||||
backend/quantized_dot.in.cpp
|
||||
backend/range.in.cpp
|
||||
backend/reduce_max.in.cpp
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
//*****************************************************************************
|
||||
// Copyright 2017-2020 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//*****************************************************************************
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/runtime/tensor.hpp"
|
||||
#include "runtime/backend.hpp"
|
||||
#include "util/all_close.hpp"
|
||||
#include "util/all_close_f.hpp"
|
||||
#include "util/known_element_types.hpp"
|
||||
#include "util/ndarray.hpp"
|
||||
#include "util/test_control.hpp"
|
||||
#include "util/test_tools.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
static string s_manifest = "${MANIFEST}";
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, quantized_conv_int32_output)
|
||||
{
|
||||
Shape shape_a{1, 1, 3, 4};
|
||||
Shape shape_b{1, 1, 3, 3};
|
||||
Shape shape_r{1, 1, 3, 4};
|
||||
vector<uint8_t> a_data = {1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4};
|
||||
vector<uint8_t> b_data = {1, 2, 3, 4, 5, 0, 0, 1, 2};
|
||||
auto A = make_shared<op::Parameter>(element::u8, shape_a);
|
||||
auto B = make_shared<op::Parameter>(element::u8, shape_b);
|
||||
auto C = make_shared<op::Parameter>(element::f32, Shape{});
|
||||
auto D = op::Constant::create(element::u8, Shape{}, {0});
|
||||
auto E = make_shared<op::Parameter>(element::f32, Shape{});
|
||||
auto F = op::Constant::create(element::u8, Shape{}, {0});
|
||||
auto G = make_shared<op::Parameter>(element::f32, Shape{});
|
||||
auto H = op::Constant::create(element::i32, Shape{}, {0});
|
||||
auto CV = make_shared<op::QuantizedConvolution>(A,
|
||||
B,
|
||||
Strides{1, 1},
|
||||
Strides{1, 1},
|
||||
CoordinateDiff{1, 1},
|
||||
CoordinateDiff{1, 1},
|
||||
Strides{1, 1},
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
element::i32);
|
||||
auto f = make_shared<Function>(NodeVector{CV}, ParameterVector{A, B, C, E, G});
|
||||
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
// Create some tensors for input/output
|
||||
auto a = backend->create_tensor(element::u8, shape_a);
|
||||
copy_data(a, a_data);
|
||||
auto b = backend->create_tensor(element::u8, shape_b);
|
||||
copy_data(b, b_data);
|
||||
auto c = backend->create_tensor(element::f32, Shape{});
|
||||
copy_data(c, vector<float>{1.0f});
|
||||
auto d = backend->create_tensor(element::f32, Shape{});
|
||||
copy_data(d, vector<float>{1.0f});
|
||||
auto e = backend->create_tensor(element::f32, Shape{});
|
||||
copy_data(e, vector<float>{1.0f});
|
||||
auto result = backend->create_tensor(element::i32, shape_r);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({result}, {a, b, c, d, e});
|
||||
EXPECT_EQ((vector<int32_t>{22, 34, 30, 32, 38, 72, 90, 43, 33, 52, 43, 39}),
|
||||
read_vector<int32_t>(result));
|
||||
}
|
||||
@@ -605,15 +605,6 @@ namespace
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_QuantizedConvolution()
|
||||
{
|
||||
op::QuantizedConvolution node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_QuantizedDot()
|
||||
{
|
||||
op::QuantizedDot node;
|
||||
|
||||
@@ -1028,114 +1028,6 @@ protected:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_TYPEID::QuantizedConvolution:
|
||||
{
|
||||
const op::QuantizedConvolution* qc =
|
||||
static_cast<const op::QuantizedConvolution*>(&node);
|
||||
|
||||
auto input_element_type = qc->get_input_element_type(0);
|
||||
auto filter_element_type = qc->get_input_element_type(1);
|
||||
auto output_element_type = qc->get_output_element_type(0);
|
||||
|
||||
if (input_element_type == element::u8 && filter_element_type == element::i8 &&
|
||||
output_element_type == element::i8)
|
||||
{
|
||||
reference::convolution<uint8_t, int8_t, int8_t, int32_t>(
|
||||
args[0]->get_data_ptr<const uint8_t>(),
|
||||
args[1]->get_data_ptr<const int8_t>(),
|
||||
out[0]->get_data_ptr<int8_t>(),
|
||||
node.get_input_shape(0),
|
||||
node.get_input_shape(1),
|
||||
node.get_output_shape(0),
|
||||
qc->get_window_movement_strides(),
|
||||
qc->get_window_dilation_strides(),
|
||||
qc->get_padding_below(),
|
||||
qc->get_padding_above(),
|
||||
qc->get_data_dilation_strides(),
|
||||
args[2]->get_data_ptr<const float>(),
|
||||
args[3]->get_data_ptr<const uint8_t>(),
|
||||
args[4]->get_data_ptr<const float>(),
|
||||
args[5]->get_data_ptr<const int8_t>(),
|
||||
args[6]->get_data_ptr<const float>(),
|
||||
args[7]->get_data_ptr<const int8_t>());
|
||||
}
|
||||
else if (input_element_type == element::u8 && filter_element_type == element::u8 &&
|
||||
output_element_type == element::u8)
|
||||
{
|
||||
reference::convolution<uint8_t, uint8_t, uint8_t, int32_t>(
|
||||
args[0]->get_data_ptr<const uint8_t>(),
|
||||
args[1]->get_data_ptr<const uint8_t>(),
|
||||
out[0]->get_data_ptr<uint8_t>(),
|
||||
node.get_input_shape(0),
|
||||
node.get_input_shape(1),
|
||||
node.get_output_shape(0),
|
||||
qc->get_window_movement_strides(),
|
||||
qc->get_window_dilation_strides(),
|
||||
qc->get_padding_below(),
|
||||
qc->get_padding_above(),
|
||||
qc->get_data_dilation_strides(),
|
||||
args[2]->get_data_ptr<const float>(),
|
||||
args[3]->get_data_ptr<const uint8_t>(),
|
||||
args[4]->get_data_ptr<const float>(),
|
||||
args[5]->get_data_ptr<const uint8_t>(),
|
||||
args[6]->get_data_ptr<const float>(),
|
||||
args[7]->get_data_ptr<const uint8_t>());
|
||||
}
|
||||
else if (input_element_type == element::u8 && filter_element_type == element::i8 &&
|
||||
output_element_type == element::i32)
|
||||
{
|
||||
reference::convolution<uint8_t, int8_t, int32_t, int32_t>(
|
||||
args[0]->get_data_ptr<const uint8_t>(),
|
||||
args[1]->get_data_ptr<const int8_t>(),
|
||||
out[0]->get_data_ptr<int32_t>(),
|
||||
node.get_input_shape(0),
|
||||
node.get_input_shape(1),
|
||||
node.get_output_shape(0),
|
||||
qc->get_window_movement_strides(),
|
||||
qc->get_window_dilation_strides(),
|
||||
qc->get_padding_below(),
|
||||
qc->get_padding_above(),
|
||||
qc->get_data_dilation_strides(),
|
||||
args[2]->get_data_ptr<const float>(),
|
||||
args[3]->get_data_ptr<const uint8_t>(),
|
||||
args[4]->get_data_ptr<const float>(),
|
||||
args[5]->get_data_ptr<const int8_t>(),
|
||||
args[6]->get_data_ptr<const float>(),
|
||||
args[7]->get_data_ptr<const int32_t>());
|
||||
}
|
||||
else if (input_element_type == element::u8 && filter_element_type == element::u8 &&
|
||||
output_element_type == element::i32)
|
||||
{
|
||||
reference::convolution<uint8_t, uint8_t, int32_t, int32_t>(
|
||||
args[0]->get_data_ptr<const uint8_t>(),
|
||||
args[1]->get_data_ptr<const uint8_t>(),
|
||||
out[0]->get_data_ptr<int32_t>(),
|
||||
node.get_input_shape(0),
|
||||
node.get_input_shape(1),
|
||||
node.get_output_shape(0),
|
||||
qc->get_window_movement_strides(),
|
||||
qc->get_window_dilation_strides(),
|
||||
qc->get_padding_below(),
|
||||
qc->get_padding_above(),
|
||||
qc->get_data_dilation_strides(),
|
||||
args[2]->get_data_ptr<const float>(),
|
||||
args[3]->get_data_ptr<const uint8_t>(),
|
||||
args[4]->get_data_ptr<const float>(),
|
||||
args[5]->get_data_ptr<const uint8_t>(),
|
||||
args[6]->get_data_ptr<const float>(),
|
||||
args[7]->get_data_ptr<const int32_t>());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "unsupported element type";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_TYPEID::QuantizedDot:
|
||||
{
|
||||
const op::QuantizedDot* qd = static_cast<const op::QuantizedDot*>(&node);
|
||||
|
||||
@@ -104,7 +104,6 @@ NGRAPH_OP(Power, ngraph::op)
|
||||
NGRAPH_OP(PRelu, ngraph::op)
|
||||
NGRAPH_OP(PriorBox, ngraph::op)
|
||||
NGRAPH_OP(Quantize, ngraph::op)
|
||||
NGRAPH_OP(QuantizedConvolution, ngraph::op)
|
||||
NGRAPH_OP(QuantizedDot, ngraph::op)
|
||||
NGRAPH_OP(Range, ngraph::op)
|
||||
NGRAPH_OP(Relu, ngraph::op)
|
||||
|
||||
@@ -1,791 +0,0 @@
|
||||
//*****************************************************************************
|
||||
// Copyright 2017-2020 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//*****************************************************************************
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "util/type_prop.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(type_prop, quantized_conv_8_bit_output)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
|
||||
ASSERT_EQ(quant_conv->get_element_type(), output_type);
|
||||
ASSERT_EQ(quant_conv->get_shape(), output_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_32_bit_output)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type i32 = element::i32;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i32;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
|
||||
ASSERT_EQ(quant_conv->get_element_type(), output_type);
|
||||
ASSERT_EQ(quant_conv->get_shape(), output_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_quantized_input_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = f32;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non-quantized input not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Input element type (f32) must be a quantized type");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_quantized_filter_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = f32;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non-quantized filter not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Filter element type (f32) must be a quantized type");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_dyn_output_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = f32;
|
||||
element::Type output_type = element::dynamic;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use dynamic output type not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Output element type must not be dynamic");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_floating_point_scale_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = i8;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto i8_zero_point = make_shared<op::Parameter>(element::i8, Shape{});
|
||||
auto u8_zero_point = make_shared<op::Parameter>(element::u8, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
u8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
scale,
|
||||
i8_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non floating point scale not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Scale must be a floating point number");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_input_zero_point_type_mismatch_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = i8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use zero point type different from input type not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(
|
||||
error.what(), "Input Zero point element type (i8) must match input element type (u8)");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_filter_zero_point_type_mismatch_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = u8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use zero point type different from filter type not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(
|
||||
error.what(),
|
||||
"Filter Zero point element type (u8) must match filter element type (i8)");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_scalar_input_zero_point_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{1, 2});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non scalar input zero point not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
"Input scale and input zero point shape must be same and 1");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_scalar_filter_zero_point_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{1, 2});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non scalar filter zero point not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
"Filter scale and filter zero point shape must be same and 1");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_scalar_output_zero_point_fails)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{1, 2});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non scalar output zero point not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
"Output scale and output zero point shape must be same and 1");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_empty_input_axes)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
AxisSet{1},
|
||||
axes,
|
||||
axes);
|
||||
FAIL() << "Attempt to use non empty input axes not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Input, filter and output AxisSet should be empty");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_empty_filter_axes)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
AxisSet{1},
|
||||
axes);
|
||||
FAIL() << "Attempt to use non empty filter axes not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Input, filter and output AxisSet should be empty");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, quantized_conv_non_empty_output_axes)
|
||||
{
|
||||
auto strides = Strides{1, 1};
|
||||
auto dilation = Strides{1, 1};
|
||||
auto padding_below = CoordinateDiff{1, 1};
|
||||
auto padding_above = CoordinateDiff{1, 1};
|
||||
element::Type f32 = element::f32;
|
||||
element::Type i8 = element::i8;
|
||||
element::Type u8 = element::u8;
|
||||
element::Type input_type = u8;
|
||||
element::Type filter_type = i8;
|
||||
element::Type output_type = i8;
|
||||
element::Type scale_type = f32;
|
||||
element::Type input_zero_point_type = u8;
|
||||
element::Type filter_zero_point_type = i8;
|
||||
element::Type output_zero_point_type = i8;
|
||||
Shape output_shape{64, 64, 220, 220};
|
||||
AxisSet axes{};
|
||||
|
||||
auto input = make_shared<op::Parameter>(input_type, Shape{64, 3, 224, 224});
|
||||
auto filter = make_shared<op::Parameter>(filter_type, Shape{64, 3, 7, 7});
|
||||
auto scale = make_shared<op::Parameter>(scale_type, Shape{});
|
||||
auto input_zero_point = make_shared<op::Parameter>(input_zero_point_type, Shape{});
|
||||
auto filter_zero_point = make_shared<op::Parameter>(filter_zero_point_type, Shape{});
|
||||
auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
|
||||
try
|
||||
{
|
||||
auto quant_conv = make_shared<op::QuantizedConvolution>(input,
|
||||
filter,
|
||||
strides,
|
||||
dilation,
|
||||
padding_below,
|
||||
padding_above,
|
||||
dilation,
|
||||
scale,
|
||||
input_zero_point,
|
||||
scale,
|
||||
filter_zero_point,
|
||||
scale,
|
||||
output_zero_point,
|
||||
output_type,
|
||||
axes,
|
||||
axes,
|
||||
AxisSet{1});
|
||||
FAIL() << "Attempt to use non empty output axes not detected";
|
||||
}
|
||||
catch (const NodeValidationFailure& error)
|
||||
{
|
||||
EXPECT_HAS_SUBSTRING(error.what(), "Input, filter and output AxisSet should be empty");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user