Removed v0 fused operations (#1263)

This commit is contained in:
Ilya Churaev 2020-07-17 19:51:04 +03:00 committed by GitHub
parent dca2ee2bcc
commit cc19e57a06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 3 additions and 3366 deletions

View File

@ -13,13 +13,12 @@
#include "ngraph/pattern/matcher.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/fused/conv_fused.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph_ops/convolution_ie.hpp"
#include "ngraph_ops/deconvolution_ie.hpp"
#include "ngraph/op/fused/group_conv.hpp"
#include "ngraph/op/group_conv.hpp"
#include "ngraph/rt_info.hpp"
#include <ngraph/pass/graph_rewrite.hpp>

View File

@ -12,11 +12,10 @@
#include "ngraph/pattern/matcher.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/fused/conv_fused.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/fused/group_conv.hpp"
#include "ngraph/op/group_conv.hpp"
#include <ngraph/pass/graph_rewrite.hpp>

View File

@ -40,8 +40,6 @@ set (SRC
builder/quantize_builder.hpp
builder/quantized_concat_builder.cpp
builder/quantized_concat_builder.hpp
builder/quantized_conv_builder.cpp
builder/quantized_conv_builder.hpp
builder/quantized_dot_builder.cpp
builder/quantized_dot_builder.hpp
builder/quantization_utils.hpp
@ -368,10 +366,6 @@ set (SRC
op/fused/batch_to_space.hpp
op/fused/clamp.cpp
op/fused/clamp.hpp
op/fused/conv_fused.cpp
op/fused/conv_fused.hpp
op/fused/crossentropy.cpp
op/fused/crossentropy.hpp
op/fused/hard_sigmoid.cpp
op/fused/hard_sigmoid.hpp
op/fused/depth_to_space.cpp
@ -380,15 +374,10 @@ set (SRC
op/fused/fake_quantize.hpp
op/fused/gelu.cpp
op/fused/gelu.hpp
op/fused/gemm.cpp
op/fused/gemm.hpp
op/fused/grn.cpp
op/fused/grn.hpp
op/fused/group_conv.hpp
op/fused/gru_cell.cpp
op/fused/gru_cell.hpp
op/fused/layer_norm.cpp
op/fused/layer_norm.hpp
op/fused/lstm_cell.cpp
op/fused/lstm_cell.hpp
op/fused/lstm_sequence.cpp
@ -401,27 +390,18 @@ set (SRC
op/fused/mvn.hpp
op/fused/normalize_l2.cpp
op/fused/normalize_l2.hpp
op/fused/partial_slice.cpp
op/fused/partial_slice.hpp
op/fused/prelu.cpp
op/fused/prelu.hpp
op/fused/rnn_cell.cpp
op/fused/rnn_cell.hpp
op/fused/scale_shift.cpp
op/fused/scale_shift.hpp
op/fused/stack.cpp
op/fused/stack.hpp
op/fused/selu.cpp
op/fused/selu.hpp
op/fused/shuffle_channels.cpp
op/fused/shuffle_channels.hpp
op/fused/softmax_crossentropy.cpp
op/fused/softmax_crossentropy.hpp
op/fused/space_to_batch.cpp
op/fused/space_to_batch.hpp
op/fused/space_to_depth.cpp
op/fused/space_to_depth.hpp
op/fused/split.hpp
op/fused/squared_difference.cpp
op/fused/squared_difference.hpp
op/fused/squeeze.cpp

View File

@ -1,85 +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 <memory>
#include "ngraph/builder/quantized_conv_builder.hpp"
using namespace std;
using namespace ngraph;
namespace ngraph
{
namespace builder
{
shared_ptr<Node> QuantizedConvolutionBuilder(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>& min_input,
const Output<Node>& max_input,
const Output<Node>& min_filter,
const Output<Node>& max_filter,
const Output<Node>& min_output,
const Output<Node>& max_output,
const ngraph::element::Type& output_type,
const ngraph::AxisSet& input_axes,
const ngraph::AxisSet& filter_axes,
const ngraph::AxisSet& output_axes)
{
auto input_scale =
quantization_utils::get_scale(min_input, max_input, input.get_element_type());
auto filter_scale =
quantization_utils::get_scale(min_filter, max_filter, filters.get_element_type());
auto output_scale = quantization_utils::get_scale(min_output, max_output, output_type);
// TODO: Check for this later
// For Builders the zero point is assumed to be zero (for now)
auto input_zero_point = op::Constant::create(input.get_element_type(), Shape{}, {0});
auto filter_zero_point = op::Constant::create(filters.get_element_type(), Shape{}, {0});
return make_shared<op::QuantizedConvolution>(
input,
filters,
window_movement_strides,
window_dilation_strides,
padding_below,
padding_above,
data_dilation_strides,
input_scale,
input_zero_point,
filter_scale,
filter_zero_point,
output_scale,
filter_zero_point, // output type will be same as filter
output_type,
input_axes,
filter_axes,
output_axes)
->add_provenance_group_members_above({input,
filters,
min_input,
max_input,
min_filter,
max_filter,
min_output,
max_output});
}
}
}

View File

@ -1,111 +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/node.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/convert.hpp"
#include "ngraph/op/quantize.hpp"
#include "ngraph/op/quantized_convolution.hpp"
#include "quantization_utils.hpp"
namespace ngraph
{
namespace builder
{
NGRAPH_API
std::shared_ptr<Node>
QuantizedConvolutionBuilder(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>& min_input,
const Output<Node>& max_input,
const Output<Node>& min_filter,
const Output<Node>& max_filter,
const Output<Node>& min_output,
const Output<Node>& max_output,
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{});
NGRAPH_API
std::shared_ptr<Node>
QuantizedConvolutionBiasBuilder(const Output<Node>& input,
const Output<Node>& filters,
const Output<Node>& bias,
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>& min_input,
const Output<Node>& max_input,
const Output<Node>& min_filter,
const Output<Node>& max_filter,
const Output<Node>& min_output,
const Output<Node>& max_output,
const bool with_relu = false);
NGRAPH_API
std::shared_ptr<Node>
QuantizedConvolutionBiasAddBuilder(const Output<Node>& input,
const Output<Node>& filters,
const Output<Node>& bias,
const Output<Node>& sum_input,
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>& min_input,
const Output<Node>& max_input,
const Output<Node>& min_filter,
const Output<Node>& max_filter,
const Output<Node>& min_output,
const Output<Node>& max_output,
const Output<Node>& min_sum_input,
const Output<Node>& max_sum_input,
const bool with_relu = false);
NGRAPH_API
std::shared_ptr<Node>
QuantizedConvolutionBiasSignedAddBuilder(const Output<Node>& input,
const Output<Node>& filters,
const Output<Node>& bias,
const Output<Node>& sum_input,
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>& min_input,
const Output<Node>& max_input,
const Output<Node>& min_filter,
const Output<Node>& max_filter,
const Output<Node>& min_output,
const Output<Node>& max_output,
const Output<Node>& min_sum_input,
const Output<Node>& max_sum_input,
const bool with_relu = false);
}
}

View File

@ -22,7 +22,7 @@
#include "default_opset.hpp"
#include "exceptions.hpp"
#include "ngraph/builder/reshape.hpp"
#include "ngraph/op/fused/group_conv.hpp"
#include "ngraph/op/group_conv.hpp"
#include "ngraph/op/slice.hpp"
#include "ngraph/op/util/attr_types.hpp"
#include "utils/convpool.hpp"

View File

@ -72,7 +72,6 @@ namespace ngraph
#include "ngraph/builder/numpy_transpose.hpp"
#include "ngraph/builder/quantize_builder.hpp"
#include "ngraph/builder/quantized_concat_builder.hpp"
#include "ngraph/builder/quantized_conv_builder.hpp"
#include "ngraph/builder/quantized_dot_builder.hpp"
#include "ngraph/builder/reduce_ops.hpp"
#include "ngraph/builder/reshape.hpp"

View File

@ -1,349 +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 "conv_fused.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/convolution.hpp"
#include "ngraph/op/get_output_element.hpp"
#include "ngraph/op/relu.hpp"
#include "ngraph/op/sum.hpp"
#include "ngraph/validation_util.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::ConvolutionBias::type_info;
constexpr NodeTypeInfo op::ConvolutionBiasAdd::type_info;
static void validate_convbias_shapes(const Node* node,
element::Type et_filters,
element::Type et_bias,
const PartialShape& filters_shape,
const PartialShape& bias_shape)
{
element::Type et_result;
NODE_VALIDATION_CHECK(node,
element::Type::merge(et_result, et_bias, et_filters),
"Element types for bias and filters do not match (bias element type: ",
et_bias,
", filters element type: ",
et_filters,
").");
NODE_VALIDATION_CHECK(node,
bias_shape.rank().is_dynamic() || bias_shape.rank().get_length() == 1,
"Bias must have a rank of 1 (bias_shape: ",
bias_shape,
").");
if (bias_shape.rank().is_static() && filters_shape.rank().is_static())
{
Dimension filter_count;
NODE_VALIDATION_CHECK(node,
Dimension::merge(filter_count, bias_shape[0], filters_shape[0]),
"Bias channel count (",
bias_shape[0],
") does not match filter output channel count (",
filters_shape[0],
").");
}
}
op::ConvolutionBias::ConvolutionBias(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias,
const Strides& window_movement_strides,
const Strides& window_dilation_strides,
const CoordinateDiff& padding_below,
const CoordinateDiff& padding_above,
const Strides& data_dilation_strides,
const bool with_relu)
: FusedOp({data_batch, filters, bias})
, 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_with_relu(with_relu)
{
constructor_validate_and_infer_types();
}
op::ConvolutionBias::ConvolutionBias(const shared_ptr<op::Convolution>& conv,
const Output<Node>& bias,
const bool with_relu)
: ConvolutionBias(conv->input_value(0),
conv->input_value(1),
bias,
conv->get_window_movement_strides(),
conv->get_window_dilation_strides(),
conv->get_padding_below(),
conv->get_padding_above(),
conv->get_data_dilation_strides(),
with_relu)
{
}
op::ConvolutionBias::ConvolutionBias(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias)
: ConvolutionBias(data_batch,
filters,
bias,
Strides(),
Strides(),
CoordinateDiff(),
CoordinateDiff(),
Strides())
{
}
/// Overrides the default shape inference utility provided by FusedOp
/// based on FusedOp decomposition.
///
/// This implementation handles partial shapes and adjust conv attributes
/// to support simplified ConvolutionBias op construction
void op::ConvolutionBias::validate_and_infer_types()
{
const PartialShape& data_batch_shape = get_input_partial_shape(0);
element::Type data_batch_et = get_input_element_type(0);
const PartialShape& filters_shape = get_input_partial_shape(1);
element::Type filters_et = get_input_element_type(1);
const PartialShape& bias_shape = get_input_partial_shape(2);
element::Type bias_et = get_input_element_type(2);
validate_convbias_shapes(this, filters_et, bias_et, filters_shape, bias_shape);
if (m_data_dilation_strides.size() == 0)
{
m_data_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape);
}
if (m_window_movement_strides.size() == 0)
{
m_window_movement_strides = conv_default_strides(this, data_batch_shape, filters_shape);
}
if (m_window_dilation_strides.size() == 0)
{
m_window_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape);
}
if (m_padding_below.size() == 0)
{
m_padding_below = conv_default_padding(this, data_batch_shape, filters_shape);
}
if (m_padding_above.size() == 0)
{
m_padding_above = conv_default_padding(this, data_batch_shape, filters_shape);
}
element::Type result_et;
PartialShape result_shape;
NODE_VALIDATION_CHECK(
this,
element::Type::merge(result_et, data_batch_et, filters_et),
"Element types for data batch and filters do not match (data batch element type: ",
data_batch_et,
", filters element type: ",
filters_et,
").");
result_shape = infer_convolution_forward(this,
data_batch_shape,
m_data_dilation_strides,
m_padding_below,
m_padding_above,
filters_shape,
m_window_movement_strides,
m_window_dilation_strides);
set_output_type(0, result_et, result_shape);
}
shared_ptr<Node> op::ConvolutionBias::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 3)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<ConvolutionBias>(new_args.at(0),
new_args.at(1),
new_args.at(2),
get_window_movement_strides(),
get_window_dilation_strides(),
get_padding_below(),
get_padding_above(),
get_data_dilation_strides(),
m_with_relu);
}
NodeVector op::ConvolutionBias::decompose_op() const
{
auto conv = make_shared<op::Convolution>(input_value(0),
input_value(1),
m_window_movement_strides,
m_window_dilation_strides,
m_padding_below,
m_padding_above,
m_data_dilation_strides);
AxisSet bcast_axes;
bcast_axes.insert(0);
for (size_t i = 2; i < conv->get_shape().size(); i++)
{
bcast_axes.insert(i);
}
auto conv_bias = make_shared<op::Add>(
conv, make_shared<op::Broadcast>(input_value(2), conv->get_shape(), bcast_axes));
if (m_with_relu)
{
return {make_shared<op::Relu>(conv_bias)};
}
else
{
return {conv_bias};
}
}
op::ConvolutionBiasAdd::ConvolutionBiasAdd(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias,
const Output<Node>& add_input,
const Strides& window_movement_strides,
const Strides& window_dilation_strides,
const CoordinateDiff& padding_below,
const CoordinateDiff& padding_above,
const Strides& data_dilation_strides,
bool with_relu)
: FusedOp({data_batch, filters, bias, add_input})
, 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_with_relu(with_relu)
{
constructor_validate_and_infer_types();
}
op::ConvolutionBiasAdd::ConvolutionBiasAdd(const std::shared_ptr<op::ConvolutionBias>& conv,
const Output<Node>& add_input,
bool with_relu)
: ConvolutionBiasAdd(conv->input_value(0),
conv->input_value(1),
conv->input_value(2),
add_input,
conv->get_window_movement_strides(),
conv->get_window_dilation_strides(),
conv->get_padding_below(),
conv->get_padding_above(),
conv->get_data_dilation_strides(),
with_relu)
{
}
/// Overrides the default shape inference utility provided by FusedOp
/// based on FusedOp decomposition.
///
/// This implementation handles partial shapes
void op::ConvolutionBiasAdd::validate_and_infer_types()
{
const PartialShape& data_batch_shape = get_input_partial_shape(0);
element::Type data_batch_et = get_input_element_type(0);
const PartialShape& filters_shape = get_input_partial_shape(1);
element::Type filters_et = get_input_element_type(1);
const PartialShape& bias_shape = get_input_partial_shape(2);
element::Type bias_et = get_input_element_type(2);
validate_convbias_shapes(this, filters_et, bias_et, filters_shape, bias_shape);
element::Type result_et;
PartialShape result_shape;
NODE_VALIDATION_CHECK(
this,
element::Type::merge(result_et, data_batch_et, filters_et),
"Element types for data batch and filters do not match (data batch element type: ",
data_batch_et,
", filters element type: ",
filters_et,
").");
result_shape = infer_convolution_forward(this,
data_batch_shape,
m_data_dilation_strides,
m_padding_below,
m_padding_above,
filters_shape,
m_window_movement_strides,
m_window_dilation_strides);
// TODO: Check result_shape is compatible with add_input
set_output_type(0, result_et, result_shape);
}
std::shared_ptr<Node>
op::ConvolutionBiasAdd::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 4)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<ConvolutionBiasAdd>(new_args.at(0),
new_args.at(1),
new_args.at(2),
new_args.at(3),
get_window_movement_strides(),
get_window_dilation_strides(),
get_padding_below(),
get_padding_above(),
get_data_dilation_strides(),
m_with_relu);
}
NodeVector op::ConvolutionBiasAdd::decompose_op() const
{
auto conv = make_shared<op::Convolution>(input_value(0),
input_value(1),
m_window_movement_strides,
m_window_dilation_strides,
m_padding_below,
m_padding_above,
m_data_dilation_strides);
AxisSet bcast_axes;
bcast_axes.insert(0);
for (size_t i = 2; i < conv->get_shape().size(); i++)
{
bcast_axes.insert(i);
}
auto conv_bias = make_shared<op::Add>(
conv, make_shared<op::Broadcast>(input_value(2), conv->get_shape(), bcast_axes));
if (m_with_relu)
{
return {make_shared<op::Relu>(conv_bias + input_value(3))};
}
else
{
return {conv_bias + input_value(3)};
}
}

View File

@ -1,139 +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/op/convolution.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
/// \brief Convolution + bias forward prop for batched convolution operation.
class NGRAPH_API ConvolutionBias : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"ConvolutionBias", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
ConvolutionBias() = default;
ConvolutionBias(const std::shared_ptr<op::Convolution>& conv,
const Output<Node>& bias,
const bool with_relu = false);
ConvolutionBias(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias,
const Strides& window_movement_strides,
const Strides& window_dilation_strides,
const CoordinateDiff& padding_below,
const CoordinateDiff& padding_above,
const Strides& data_dilation_strides,
const bool with_relu = false);
ConvolutionBias(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias);
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; }
Output<Node> get_bias() { return input_value(2); }
Output<Node> get_filters() { return input_value(1); }
Output<Node> get_data_batch() { return input_value(0); }
bool with_relu() const { return m_with_relu; }
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
virtual NodeVector decompose_op() const override;
virtual void validate_and_infer_types() 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;
bool m_with_relu;
};
class NGRAPH_API ConvolutionBiasAdd : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"ConvolutionBiasAdd", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
ConvolutionBiasAdd() = default;
ConvolutionBiasAdd(const std::shared_ptr<op::v0::ConvolutionBias>& conv,
const Output<Node>& sum_input,
bool with_relu = false);
ConvolutionBiasAdd(const Output<Node>& data_batch,
const Output<Node>& filters,
const Output<Node>& bias,
const Output<Node>& sum_input,
const Strides& window_movement_strides,
const Strides& window_dilation_strides,
const CoordinateDiff& padding_below,
const CoordinateDiff& padding_above,
const Strides& data_dilation_strides,
bool with_relu = false);
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; }
Output<Node> get_filters() { return input_value(1); }
Output<Node> get_data_batch() { return input_value(0); }
bool with_relu() const { return m_with_relu; }
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
virtual NodeVector decompose_op() const override;
virtual void validate_and_infer_types() 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;
bool m_with_relu;
};
}
using v0::ConvolutionBias;
using v0::ConvolutionBiasAdd;
}
}

View File

@ -1,291 +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 "ngraph/op/fused/crossentropy.hpp"
#include "ngraph/builder/make_constant.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/convert.hpp"
#include "ngraph/op/divide.hpp"
#include "ngraph/op/log.hpp"
#include "ngraph/op/multiply.hpp"
#include "ngraph/op/negative.hpp"
#include "ngraph/op/not_equal.hpp"
#include "ngraph/op/one_hot.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/subtract.hpp"
#include "ngraph/op/sum.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::CrossEntropy::type_info;
op::CrossEntropy::CrossEntropy(const Output<Node>& arg1,
const Output<Node>& arg2,
bool soft_label,
int64_t ignore_index)
: FusedOp({arg1, arg2})
, m_soft_label(soft_label)
, m_ignore_index(ignore_index)
{
constructor_validate_and_infer_types();
}
static AxisVector get_axis_vector(size_t rank)
{
AxisVector axis_vector;
for (size_t i = 0; i < rank; i++)
{
axis_vector.push_back(i);
}
return axis_vector;
}
static Shape get_result_shape(Shape& target_shape, int start, int end)
{
Shape result;
for (size_t i = start; i < end; i++)
{
result.push_back(target_shape[i]);
}
return result;
}
static Output<Node> get_2d_tensor(Output<Node> node)
{
if (node.get_shape().size() == 2)
{
return node;
}
Shape node_shape = node.get_shape();
size_t rank = node_shape.size();
Shape result_shape{(shape_size(node_shape) / node_shape[rank - 1]), node_shape[rank - 1]};
auto reshape = std::make_shared<ngraph::op::Reshape>(node, get_axis_vector(rank), result_shape);
return reshape;
}
static std::shared_ptr<Node> expand_shape(std::shared_ptr<Node> result, Output<Node> original)
{
Shape result_shape = result->get_shape();
Shape original_shape = original.get_shape();
if (result_shape == original_shape && result_shape.size() == 2)
{
return result;
}
size_t original_rank = original_shape.size();
size_t result_rank = result_shape.size();
// expand the first dimension of the computed result to match the original tensor shape
Shape new_shape = get_result_shape(original_shape, 0, original_rank - 1);
// restore the last dimension of computed result
new_shape.push_back(result_shape[result_rank - 1]);
if (new_shape.size() != original_shape.size())
{
throw ngraph_error(
"CrossEntropy shape size mismatch in restoring the original tensor shape");
}
auto reshape = std::make_shared<ngraph::op::Reshape>(result, AxisVector{0, 1}, new_shape);
return reshape;
}
// create mask based on ignore_index
static std::shared_ptr<ngraph::Node>
create_mask(Output<Node> labels, Output<Node> input, int64_t ignore_index)
{
auto mask_constant =
ngraph::op::Constant::create(labels.get_element_type(), labels.get_shape(), {ignore_index});
auto not_equal = std::make_shared<ngraph::op::NotEqual>(labels, mask_constant);
auto convert = std::make_shared<ngraph::op::Convert>(not_equal, input.get_element_type());
return convert;
}
NodeVector op::CrossEntropy::decompose_op() const
{
// we will reshape the labels and input tensor to 2d
auto input_to_normalize = get_2d_tensor(input_value(0));
auto labels = get_2d_tensor(input_value(1));
auto reduction_axis = input_to_normalize.get_shape().size() - 1;
auto create_xe = [&](const Output<Node>& one_hot, const Output<Node>& input) {
auto node_log = std::make_shared<ngraph::op::Log>(input);
auto node_mul = one_hot * node_log;
auto node_sum = std::make_shared<ngraph::op::Sum>(
node_mul, AxisSet{static_cast<size_t>(reduction_axis)});
return -node_sum;
};
// mask
std::shared_ptr<ngraph::Node> mask = create_mask(labels, input_to_normalize, m_ignore_index);
if (m_soft_label)
{
// insert dtype conversion if required
if (labels.get_element_type() != input_to_normalize.get_element_type())
{
labels = std::make_shared<ngraph::op::Convert>(labels,
input_to_normalize.get_element_type());
}
if (labels.get_shape()[reduction_axis] == 1)
{
auto reshape_labels = std::make_shared<ngraph::op::Reshape>(
labels, AxisVector{0, 1}, Shape{labels.get_shape().at(0)});
labels = std::make_shared<ngraph::op::Broadcast>(
reshape_labels,
input_to_normalize.get_shape(),
AxisSet{input_to_normalize.get_shape().size() - 1});
}
auto xe = create_xe(labels, input_to_normalize);
auto reshape_xe = std::make_shared<ngraph::op::Reshape>(
xe, AxisVector{0}, Shape{xe->get_shape().at(0), 1});
return {expand_shape(reshape_xe, input_value(0))};
}
else
{
// we will have one_hot encoding on labels if softmax_labels = false
size_t one_hot_axis = input_to_normalize.get_shape().size() - 1;
auto reshape_labels =
make_shared<op::Reshape>(labels, AxisVector{0, 1}, Shape{labels.get_shape().at(0)});
auto one_hot_labels = std::make_shared<ngraph::op::OneHot>(
reshape_labels, input_to_normalize.get_shape(), one_hot_axis);
auto convert_one_hot = std::make_shared<ngraph::op::Convert>(
one_hot_labels, input_to_normalize.get_element_type());
// calculate loss
auto xe = create_xe(convert_one_hot, input_to_normalize);
auto reshape_xe = std::make_shared<ngraph::op::Reshape>(
xe, AxisVector{0}, Shape{xe->get_shape().at(0), 1});
if (m_ignore_index > 0)
{
return {reshape_xe * mask};
}
return {expand_shape(reshape_xe, input_value(0))};
}
}
shared_ptr<Node> op::CrossEntropy::clone_with_new_inputs(const OutputVector& new_args) const
{
check_new_args_count(this, new_args);
return make_shared<CrossEntropy>(new_args.at(0), new_args.at(1), m_soft_label, m_ignore_index);
}
void op::CrossEntropy::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
set_output_type(0, get_input_element_type(0), PartialShape::dynamic());
if (is_dynamic())
{
return;
}
}
constexpr NodeTypeInfo op::CrossEntropyBackprop::type_info;
op::CrossEntropyBackprop::CrossEntropyBackprop(const Output<Node>& input,
const Output<Node>& labels,
const Output<Node>& delta,
bool soft_label,
int64_t ignore_index)
: FusedOp({input, labels, delta})
, m_soft_label(soft_label)
, m_ignore_index(ignore_index)
{
constructor_validate_and_infer_types();
}
void op::CrossEntropyBackprop::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
set_output_type(0, get_input_element_type(0), PartialShape::dynamic());
}
shared_ptr<Node> op::CrossEntropyBackprop::clone_with_new_inputs(const OutputVector& new_args) const
{
check_new_args_count(this, new_args);
return make_shared<CrossEntropyBackprop>(
new_args.at(0), new_args.at(1), new_args.at(2), m_soft_label, m_ignore_index);
}
NodeVector op::CrossEntropyBackprop::decompose_op() const
{
auto input = get_2d_tensor(input_value(0));
auto labels = get_2d_tensor(input_value(1));
auto delta = get_2d_tensor(input_value(2));
auto rank = input.get_shape().size();
size_t one_hot_axis = delta.get_shape().size() - 1;
// always reduces the sum on the last axis
auto reduction_axis = delta.get_shape().size() - 1;
// mask
std::shared_ptr<ngraph::Node> mask = nullptr;
// remove trailing ones from delta
auto delta_reshape = std::make_shared<ngraph::op::Reshape>(
delta, AxisVector{0, 1}, Shape{delta.get_shape().at(0)});
auto delta_bcast = std::make_shared<ngraph::op::Broadcast>(
delta_reshape, input.get_shape(), AxisSet{rank - 1});
if (!m_soft_label)
{
// ignore mask
if (m_ignore_index > 0)
{
mask = create_mask(labels, input, m_ignore_index);
mask = std::make_shared<ngraph::op::Reshape>(
mask, AxisVector{0, 1}, Shape{mask->get_shape().at(0)});
mask =
std::make_shared<ngraph::op::Broadcast>(mask, input.get_shape(), AxisSet{rank - 1});
}
if (labels.get_shape()[reduction_axis] == 1)
{
labels =
make_shared<op::Reshape>(labels, AxisVector{0, 1}, Shape{labels.get_shape().at(0)});
}
// one hot encoding of labels
auto one_hot =
std::make_shared<ngraph::op::OneHot>(labels, input.get_shape(), one_hot_axis);
labels = std::make_shared<ngraph::op::Convert>(one_hot, input.get_element_type());
}
std::shared_ptr<ngraph::Node> xe_grad =
std::make_shared<ngraph::op::Divide>(-labels * delta_bcast, input);
if (!m_soft_label && m_ignore_index > 0)
{
xe_grad = xe_grad * mask;
}
return {expand_shape(xe_grad, input_value(0))};
}

View File

@ -1,102 +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/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
class NGRAPH_API CrossEntropy : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"CrossEntropy", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
CrossEntropy() = default;
/// \brief CrossEntropy for computing loss
/// \param arg1 Node that produces the input tensor
/// \param arg2 Node that produces ground truth lables for the input
/// \param soft_label flag indicating whether to interpretate the given labels as
/// soft
/// labels
/// \param ignore_index Specifies a target value that is ignored and does not
/// contribute
/// to the input gradient Only valid if soft_label is set to False
CrossEntropy(const Output<Node>& arg1,
const Output<Node>& arg2,
bool soft_label = false,
int64_t ignore_index = -100);
virtual NodeVector decompose_op() const override;
void pre_validate_and_infer_types() override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
bool get_soft_label() const { return m_soft_label; }
int64_t get_ignore_index() const { return m_ignore_index; }
private:
bool m_soft_label;
int64_t m_ignore_index;
};
class NGRAPH_API CrossEntropyBackprop : public util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"CrossEntropyBackprop", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
CrossEntropyBackprop() = default;
/// \brief Backprop for CrossEntropy
/// \param input Node that produces tensor from the fprop
/// \param labels Node that produces ground truth labels for input
/// \param delta Node that produces the delta during bprop
/// \param soft_label flag indicating whether to interpretate the given labels as
/// soft
/// labels
/// \param ignore_index Specifies a target value that is ignored and does not
/// contribute
/// to the input gradient Only valid if soft_label is set to False
CrossEntropyBackprop(const Output<Node>& input,
const Output<Node>& labels,
const Output<Node>& delta,
bool soft_label = false,
int64_t ignore_index = -100);
virtual NodeVector decompose_op() const override;
void pre_validate_and_infer_types() override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
bool get_soft_label() const { return m_soft_label; }
int64_t get_ignore_index() const { return m_ignore_index; }
private:
bool m_soft_label;
int64_t m_ignore_index;
};
}
using v0::CrossEntropy;
using v0::CrossEntropyBackprop;
}
}

View File

@ -1,93 +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 "ngraph/op/fused/gemm.hpp"
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/builder/reshape.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/dot.hpp"
#include "ngraph/op/fused/matmul.hpp"
#include "ngraph/op/multiply.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::Gemm::type_info;
op::Gemm::Gemm(const Output<Node>& A,
const Output<Node>& B,
const Output<Node>& C,
double alpha,
double beta,
bool transA,
bool transB)
: FusedOp({A, B, C})
, m_alpha{alpha}
, m_beta{beta}
, m_transA{transA}
, m_transB{transB}
{
constructor_validate_and_infer_types();
}
NodeVector op::Gemm::decompose_op() const
{
auto A = input_value(0);
auto B = input_value(1);
auto C = input_value(2);
if (m_transA)
{
A = builder::transpose(A);
}
if (m_transB)
{
B = builder::transpose(B);
}
A = builder::flatten(A, 1);
B = builder::flatten(B, 1);
// A' * B'
std::shared_ptr<Node> a_dot_b = std::make_shared<op::Dot>(A, B);
// alpha
std::shared_ptr<Node> alpha_node = std::make_shared<op::Constant>(
a_dot_b->get_element_type(), a_dot_b->get_shape(), std::vector<double>{m_alpha});
// alpha * A' * B'
a_dot_b = std::make_shared<op::Multiply>(alpha_node, a_dot_b);
// beta * C
std::shared_ptr<Node> beta_node = std::make_shared<op::Constant>(
C.get_element_type(), C.get_shape(), std::vector<double>{m_beta});
C = std::make_shared<op::Multiply>(beta_node, C);
// alpha * A' * B' + beta * C
// The input tensor `C` should be "unidirectionally broadcastable" to the `a_dot_b` tensor.
auto broadcasted_c = builder::numpy_broadcast(C, a_dot_b->get_shape());
return {std::make_shared<op::Add>(a_dot_b, broadcasted_c)};
}
shared_ptr<Node> op::Gemm::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 3)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<Gemm>(
new_args.at(0), new_args.at(1), new_args.at(2), m_alpha, m_beta, m_transA, m_transB);
}

View File

@ -1,80 +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/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
/// \brief Operator performing General Matrix multiplication.
///
/// \note More information:
/// https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3
///
/// A' = transpose(A) if transA else A
/// B' = transpose(B) if transB else B
///
/// Compute Y = alpha * A' * B' + beta * C
///
class NGRAPH_API Gemm : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"Gemm", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
Gemm() = default;
/// \brief Constructs an Gemm operation.
///
/// \param A Input tensor A
/// \param B Input tensor B
/// \param C Input tensor C
/// \param alpha Scalar multiplier for the product of input tensors A * B
/// \param beta Scalar multiplier for input tensor C
/// \param transA Whether A should be transposed
/// \param transB Whether B should be transposed
Gemm(const Output<Node>& A,
const Output<Node>& B,
const Output<Node>& C,
double alpha = 1.0,
double beta = 1.0,
bool transA = false,
bool transB = false);
virtual NodeVector decompose_op() const override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
double get_alpha() const { return m_alpha; }
double get_beta() const { return m_beta; }
bool get_transA() const { return m_transA; }
bool get_transB() const { return m_transB; }
private:
double m_alpha;
double m_beta;
bool m_transA;
bool m_transB;
};
}
using v0::Gemm;
}
}

View File

@ -1,17 +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 "ngraph/op/group_conv.hpp"

View File

@ -1,233 +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 <cmath>
#include <numeric>
#include "ngraph/builder/make_constant.hpp"
#include "ngraph/builder/reduce_ops.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/divide.hpp"
#include "ngraph/op/fused/layer_norm.hpp"
#include "ngraph/op/multiply.hpp"
#include "ngraph/op/negative.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/sqrt.hpp"
#include "ngraph/op/subtract.hpp"
#include "ngraph/op/sum.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::LayerNorm::type_info;
op::LayerNorm::LayerNorm(const Output<Node>& data,
const Output<Node>& scale,
const Output<Node>& bias,
bool keep_stats,
int64_t begin_norm_axis,
double epsilon)
: FusedOp({data, scale, bias})
, m_keep_stats(keep_stats)
, m_use_affine(true)
, m_begin_norm_axis(begin_norm_axis)
, m_epsilon(epsilon)
{
constructor_validate_and_infer_types();
}
op::LayerNorm::LayerNorm(const Output<Node>& data,
bool keep_stats,
int64_t begin_norm_axis,
double epsilon)
: FusedOp({data})
, m_keep_stats(keep_stats)
, m_use_affine(false)
, m_begin_norm_axis(begin_norm_axis)
, m_epsilon(epsilon)
{
constructor_validate_and_infer_types();
}
// All input shape should be static by this point
NodeVector op::LayerNorm::decompose_op() const
{
const PartialShape& data_shape = get_input_partial_shape(0);
if (data_shape.is_dynamic())
{
throw ngraph_error("Data needs to have static shape to decompose");
}
if (m_use_affine)
{
const PartialShape& scale_shape = get_input_partial_shape(1);
const PartialShape& bias_shape = get_input_partial_shape(2);
if (scale_shape.is_dynamic())
{
throw ngraph_error("Scale needs to have static shape to decompose");
}
if (bias_shape.is_dynamic())
{
throw ngraph_error("Bias needs to have static shape to decompose");
}
}
// Compute real axis
auto shape = data_shape.to_shape();
int64_t n_axis = m_begin_norm_axis >= 0 ? m_begin_norm_axis : shape.size() + m_begin_norm_axis;
// Get input data
auto data = input_value(0);
// Compute mean
std::vector<size_t> post_reduction_axes(shape.size() - n_axis);
std::iota(post_reduction_axes.begin(), post_reduction_axes.end(), n_axis);
auto mean = builder::mean(data, post_reduction_axes);
AxisSet post_axis_set;
for (size_t i = static_cast<size_t>(n_axis); i < shape.size(); i++)
{
post_axis_set.insert(i);
}
auto b_mean = make_shared<ngraph::op::Broadcast>(mean, shape, post_axis_set);
// Compute variance
auto var = builder::variance(data, post_reduction_axes);
// Compute standard deviation with epsilon
auto epsilon = builder::make_constant(var->get_element_type(), var->get_shape(), m_epsilon);
auto stddev = make_shared<op::Sqrt>(var + epsilon);
auto b_stddev = make_shared<op::Broadcast>(stddev, shape, post_axis_set);
// Get normalized input
auto norm = (data - b_mean) / b_stddev;
// Apply affine transformation
if (m_use_affine)
{
AxisSet pre_axis_set;
for (size_t i = 0; i < static_cast<size_t>(n_axis); i++)
{
pre_axis_set.insert(i);
}
auto scale = input_value(1);
auto bias = input_value(2);
auto scale_shape = get_input_partial_shape(1).to_shape();
if (shape.size() - n_axis != scale_shape.size())
{
Shape reshape_shape(shape.begin() + m_begin_norm_axis, shape.end());
scale = make_shared<op::Reshape>(scale, AxisVector{0}, reshape_shape);
bias = make_shared<op::Reshape>(bias, AxisVector{0}, reshape_shape);
}
auto b_scale = make_shared<op::Broadcast>(scale, shape, pre_axis_set);
auto b_bias = make_shared<op::Broadcast>(bias, shape, pre_axis_set);
norm = norm * b_scale + b_bias;
}
// Return output nodes
NodeVector retval;
retval.emplace_back(norm);
if (m_keep_stats)
{
retval.emplace_back(mean);
retval.emplace_back(var);
}
return retval;
}
shared_ptr<Node> op::LayerNorm::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 1 && new_args.size() != 3)
{
throw ngraph_error("Incorrect number of new arguments");
}
if (!m_use_affine)
{
return make_shared<LayerNorm>(new_args.at(0), m_keep_stats, m_begin_norm_axis, m_epsilon);
}
else
{
return make_shared<LayerNorm>(new_args.at(0),
new_args.at(1),
new_args.at(2),
m_keep_stats,
m_begin_norm_axis,
m_epsilon);
}
}
void op::LayerNorm::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
const PartialShape& data_shape = get_input_partial_shape(0);
Rank data_rank = data_shape.rank();
int64_t d_rank = -1;
int64_t n_axis = -1;
if (data_rank.is_static())
{
d_rank = data_rank.get_length();
n_axis = m_begin_norm_axis >= 0 ? m_begin_norm_axis : d_rank + m_begin_norm_axis;
NODE_VALIDATION_CHECK(
this, n_axis >= 0 && n_axis < d_rank, "begin_norm_axis is out of range");
if (m_use_affine)
{
const PartialShape& scale_shape = get_input_partial_shape(1);
const PartialShape& bias_shape = get_input_partial_shape(2);
Rank scale_rank = scale_shape.rank();
Rank bias_rank = bias_shape.rank();
if (scale_rank.is_static() && bias_rank.is_static())
{
int64_t s_rank = scale_rank.get_length();
int64_t b_rank = bias_rank.get_length();
NODE_VALIDATION_CHECK(this,
s_rank == b_rank &&
((s_rank == (d_rank - n_axis)) || s_rank == 1),
"Scale and/or bias rank is incorrect");
}
}
}
if (m_keep_stats)
{
set_output_size(3);
// output shape: data_shape[:begin_norm_axis]
if (d_rank > 0)
{
std::vector<Dimension> stats_dim;
for (int64_t i = 0; i < n_axis; i++)
{
stats_dim.emplace_back(data_shape[i]);
}
PartialShape stats_shape(stats_dim);
set_output_type(1, input_element_type, stats_shape);
set_output_type(2, input_element_type, stats_shape);
}
else // set shape to dynamic
{
set_output_type(1, input_element_type, PartialShape::dynamic());
set_output_type(2, input_element_type, PartialShape::dynamic());
}
}
PartialShape norm_shape{data_shape};
set_output_type(0, input_element_type, norm_shape);
}

View File

@ -1,77 +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/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
/// \brief Layer Normalization
///
class NGRAPH_API LayerNorm : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"LayerNorm", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
LayerNorm() = default;
/// \brief Constructs an LayerNorm operation.
///
/// \param data Input tensor
/// \param scale Scale tensor
/// \param bias Bias tensor
/// \param keep_stats Generated addition output mean and variance, default true
/// \param begin_norm_axis Axis where normalization starts, default - -1
/// \param epsilon Small number to add for stability of rsqrt, default 1e-5
LayerNorm(const Output<Node>& data,
const Output<Node>& scale,
const Output<Node>& bias,
bool keep_stats = true,
int64_t begin_norm_axis = 1,
double epsilon = 1e-5);
LayerNorm(const Output<Node>& data,
bool keep_stats = true,
int64_t begin_norm_axis = 1,
double epsilon = 1e-5);
virtual NodeVector decompose_op() const override;
void pre_validate_and_infer_types() override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
bool get_keep_stats() const { return m_keep_stats; }
bool get_use_affine() const { return m_use_affine; }
double get_epsilon() const { return m_epsilon; }
int64_t get_begin_norm_axis() const { return m_begin_norm_axis; }
private:
bool m_keep_stats{true};
bool m_use_affine{true};
int64_t m_begin_norm_axis{1};
double m_epsilon{1e-5};
};
}
using v0::LayerNorm;
}
}

View File

@ -54,10 +54,5 @@ namespace ngraph
AutoBroadcastSpec m_auto_broadcast;
};
}
namespace v0
{
using v1::Mod;
}
}
}

View File

@ -1,146 +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 <cmath>
#include <numeric>
#include "ngraph/builder/make_constant.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/fused/partial_slice.hpp"
#include "ngraph/op/replace_slice.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/slice.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::PartialSlice::type_info;
op::PartialSlice::PartialSlice(const Output<Node>& data,
const AxisVector& axes,
const std::vector<int64_t>& lower_bounds,
const std::vector<int64_t>& upper_bounds,
const AxisVector& decrease_axes)
: FusedOp({data})
, m_axes(axes)
, m_lower_bounds(lower_bounds)
, m_upper_bounds(upper_bounds)
, m_decrease_axes(decrease_axes)
{
constructor_validate_and_infer_types();
}
// All input shape should be static by this point
NodeVector op::PartialSlice::decompose_op() const
{
const PartialShape& data_pshape = get_input_partial_shape(0);
if (data_pshape.is_dynamic())
{
throw ngraph_error("Data needs to have static shape to decompose");
}
auto data = input_value(0);
auto data_shape = data.get_shape();
auto axes = get_axes();
auto starts = get_lower_bounds();
auto ends = get_upper_bounds();
auto decrease_axes = get_decrease_axes();
Coordinate ng_start, ng_end;
int axis_length, start, end;
for (size_t i = 0; i < data_shape.size(); ++i)
{
ng_start.push_back(0);
ng_end.push_back(data_shape[i]);
}
for (size_t i = 0; i < axes.size(); ++i)
{
axis_length = data_shape[axes[i]];
start = starts[i] < 0 ? (starts[i] + axis_length) : starts[i];
end = ends[i] < 0 ? (ends[i] + axis_length) : ends[i];
start = max(start, 0);
end = max(end, 0);
start = min(start, axis_length);
end = min(end, axis_length);
start = min(start, end);
ng_start[axes[i]] = start;
ng_end[axes[i]] = end;
}
auto sliced = std::make_shared<op::Slice>(data, ng_start, ng_end);
auto out_shape = sliced->get_shape();
Shape out_reshape_shape{};
if (decrease_axes.size() > 0)
{
auto new_out_shape = out_shape;
for (size_t i = 0; i < decrease_axes.size(); ++i)
{
int idx = decrease_axes[i];
NGRAPH_CHECK(out_shape[idx] == 1, "Decrease dim should be 1");
new_out_shape[idx] = 0;
}
for (size_t i = 0; i < out_shape.size(); ++i)
{
if (new_out_shape[i] != 0)
{
out_reshape_shape.push_back(out_shape[i]);
}
}
if (out_reshape_shape.size() == 0)
{
out_reshape_shape.push_back(1);
}
}
else
{
out_reshape_shape = out_shape;
}
auto out =
std::make_shared<op::Reshape>(sliced, get_default_order(out_shape), out_reshape_shape);
return {out};
}
shared_ptr<Node> op::PartialSlice::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 1)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<PartialSlice>(
new_args.at(0), m_axes, m_lower_bounds, m_upper_bounds, m_decrease_axes);
}
void op::PartialSlice::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
PartialShape data_pshape = get_input_partial_shape(0);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
if (data_pshape.is_dynamic())
{
set_output_type(0, input_element_type, PartialShape::dynamic());
}
}

View File

@ -1,71 +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/axis_vector.hpp"
#include "ngraph/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
/// \brief pdpd slice op
///
class NGRAPH_API PartialSlice : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"PartialSlice", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
PartialSlice() = default;
/// \brief Constructs an PartialSlice operation.
///
/// \param data Input tensor
/// \param axes Axes that lower and upper bounds apply to
/// \param lower_bounds Starting indices of corresponding axis in `axes`
/// \param upper_bounds Ending indices of corresponding axis in `axes`
/// \param decrease_axis Axes to be dropped (dimension will be one)
PartialSlice(const Output<Node>& data,
const AxisVector& axes,
const std::vector<int64_t>& lower_bounds,
const std::vector<int64_t>& upper_bounds,
const AxisVector& decrease_axes);
virtual NodeVector decompose_op() const override;
void pre_validate_and_infer_types() override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
const AxisVector& get_axes() const { return m_axes; }
const std::vector<int64_t>& get_lower_bounds() const { return m_lower_bounds; }
const std::vector<int64_t>& get_upper_bounds() const { return m_upper_bounds; }
const AxisVector& get_decrease_axes() const { return m_decrease_axes; }
private:
AxisVector m_axes;
std::vector<int64_t> m_lower_bounds;
std::vector<int64_t> m_upper_bounds;
AxisVector m_decrease_axes;
};
}
using v0::PartialSlice;
}
}

View File

@ -1,57 +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 "scale_shift.hpp"
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/multiply.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::ScaleShift::type_info;
op::ScaleShift::ScaleShift(const Output<Node>& data,
const Output<Node>& scale,
const Output<Node>& shift)
: FusedOp({data, scale, shift})
{
constructor_validate_and_infer_types();
}
NodeVector op::ScaleShift::decompose_op() const
{
auto data = input_value(0);
auto scale = input_value(1);
auto shift = input_value(2);
// broadcast all data
auto broadcasted_nodes = builder::numpy_broadcast_outputs({data, scale, shift});
data = broadcasted_nodes[0];
scale = broadcasted_nodes[1];
shift = broadcasted_nodes[2];
return {scale * data + shift};
}
shared_ptr<Node> op::ScaleShift::clone_with_new_inputs(const OutputVector& new_args) const
{
if (new_args.size() != 3)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<ScaleShift>(new_args.at(0), new_args.at(1), new_args.at(2));
}

View File

@ -1,56 +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/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
/// \brief Operator performing Scale Shift transformation.
///
/// Y = Scale * Data + Shift
///
class NGRAPH_API ScaleShift : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"ScaleShift", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
ScaleShift() = default;
/// \brief Constructs an ScaleShift operation.
///
/// \param data Input tensor
/// \param scale Input tensor that scale input data
/// \param shift Input tensor that shift input data
ScaleShift(const Output<Node>& data,
const Output<Node>& scale,
const Output<Node>& shift);
virtual NodeVector decompose_op() const override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
};
}
using v0::ScaleShift;
}
}

View File

@ -1,158 +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 "ngraph/op/fused/softmax_crossentropy.hpp"
#include "ngraph/builder/make_constant.hpp"
#include "ngraph/op/constant.hpp"
#include "ngraph/op/convert.hpp"
#include "ngraph/op/exp.hpp"
#include "ngraph/op/log.hpp"
#include "ngraph/op/max.hpp"
#include "ngraph/op/multiply.hpp"
#include "ngraph/op/negative.hpp"
#include "ngraph/op/not_equal.hpp"
#include "ngraph/op/one_hot.hpp"
#include "ngraph/op/reshape.hpp"
#include "ngraph/op/softmax.hpp"
#include "ngraph/op/subtract.hpp"
#include "ngraph/op/sum.hpp"
using namespace std;
using namespace ngraph;
constexpr NodeTypeInfo op::SoftmaxCrossEntropy::type_info;
op::SoftmaxCrossEntropy::SoftmaxCrossEntropy(const Output<Node>& arg1,
const Output<Node>& arg2,
bool soft_label,
int64_t ignore_index)
: FusedOp({arg1, arg2})
, m_soft_label(soft_label)
, m_ignore_index(ignore_index)
{
constructor_validate_and_infer_types();
}
NodeVector op::SoftmaxCrossEntropy::decompose_op() const
{
auto input_to_normalize = input_value(0);
auto labels = input_value(1);
auto reduction_axis = input_to_normalize.get_shape().size() - 1;
auto create_mask = [&]() -> std::shared_ptr<ngraph::Node> {
// ignore mask
auto mask_constant = ngraph::op::Constant::create(
labels.get_element_type(), labels.get_shape(), {m_ignore_index});
auto not_equal = std::make_shared<ngraph::op::NotEqual>(labels, mask_constant);
auto convert =
std::make_shared<ngraph::op::Convert>(not_equal, input_to_normalize.get_element_type());
auto reshape = std::make_shared<ngraph::op::Reshape>(
convert, AxisVector{0, 1}, Shape{convert->get_shape().at(0), 1});
return reshape;
};
auto create_xe = [&](std::shared_ptr<ngraph::Node> one_hot,
std::shared_ptr<ngraph::Node> input_softmax) {
auto node_log = std::make_shared<ngraph::op::Log>(input_softmax);
auto node_mul = one_hot * node_log;
auto node_sum = std::make_shared<ngraph::op::Sum>(
node_mul, AxisSet{static_cast<size_t>(reduction_axis)});
return -node_sum;
};
if (m_soft_label)
{
// always reduces the sum on the last axis
auto max_xj = std::make_shared<ngraph::op::Max>(
input_to_normalize, AxisSet{static_cast<size_t>(reduction_axis)});
auto broadcast_max_xj = std::make_shared<ngraph::op::Broadcast>(
max_xj, input_to_normalize.get_shape(), AxisSet{1});
auto subtract =
std::make_shared<ngraph::op::Subtract>(input_to_normalize, broadcast_max_xj);
auto exp = std::make_shared<ngraph::op::Exp>(subtract);
auto sum_over_j =
std::make_shared<ngraph::op::Sum>(exp, AxisSet{static_cast<size_t>(reduction_axis)});
auto log_sum_over_j = std::make_shared<ngraph::op::Log>(sum_over_j);
auto subtract_max_xj_from_input =
std::make_shared<ngraph::op::Subtract>(input_to_normalize, broadcast_max_xj);
auto broadcast_log = std::make_shared<ngraph::op::Broadcast>(
log_sum_over_j, subtract_max_xj_from_input->get_shape(), AxisSet{1});
auto subtract_max_xj_from_input_from_log_sum_over_j =
std::make_shared<ngraph::op::Subtract>(subtract_max_xj_from_input, broadcast_log);
// insert dtype conversion if required
if (labels.get_element_type() != input_to_normalize.get_element_type())
{
labels = std::make_shared<ngraph::op::Convert>(labels,
input_to_normalize.get_element_type());
}
auto multiply = std::make_shared<ngraph::op::Multiply>(
labels, subtract_max_xj_from_input_from_log_sum_over_j);
auto sum_over_k = std::make_shared<ngraph::op::Sum>(
multiply, AxisSet{static_cast<size_t>(reduction_axis)});
auto negate_summation = std::make_shared<ngraph::op::Negative>(sum_over_k);
auto reshape = std::make_shared<ngraph::op::Reshape>(
negate_summation, AxisVector{0}, Shape{input_to_normalize.get_shape().at(0), 1});
return {reshape};
}
else
{
// we will have one_hot encoding on labels if softmax_lables = false
size_t one_hot_axis = input_to_normalize.get_shape().size() - 1;
size_t softmax_axis = input_to_normalize.get_shape().size() - 1;
auto reshape_labels =
make_shared<op::Reshape>(labels, AxisVector{0, 1}, Shape{labels.get_shape().at(0)});
auto one_hot_labels = std::make_shared<ngraph::op::OneHot>(
reshape_labels, input_to_normalize.get_shape(), one_hot_axis);
auto convert_one_hot = std::make_shared<ngraph::op::Convert>(
one_hot_labels, input_to_normalize.get_element_type());
auto mask = create_mask();
// softmax will be applied on the input to cross_entropy
auto softmax =
std::make_shared<ngraph::op::Softmax>(input_to_normalize, AxisSet{softmax_axis});
auto xe = create_xe(convert_one_hot, softmax);
auto reshape_xe = std::make_shared<ngraph::op::Reshape>(
xe, AxisVector{0}, Shape{xe->get_shape().at(0), 1});
return {reshape_xe * mask};
}
}
void op::SoftmaxCrossEntropy::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
PartialShape data_pshape = get_input_partial_shape(0);
PartialShape labels_pshape = get_input_partial_shape(1);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
if (data_pshape.is_dynamic() || labels_pshape.is_dynamic())
{
set_output_type(0, input_element_type, PartialShape::dynamic());
}
}
shared_ptr<Node> op::SoftmaxCrossEntropy::clone_with_new_inputs(const OutputVector& new_args) const
{
check_new_args_count(this, new_args);
return make_shared<SoftmaxCrossEntropy>(
new_args.at(0), new_args.at(1), m_soft_label, m_ignore_index);
}

View File

@ -1,65 +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/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
namespace ngraph
{
namespace op
{
namespace v0
{
class NGRAPH_API SoftmaxCrossEntropy : public ngraph::op::util::FusedOp
{
public:
static constexpr NodeTypeInfo type_info{"SoftmaxCrossEntropy", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
SoftmaxCrossEntropy() = default;
/// \brief Softamax + CrossEntropy for numerical stabilization
/// \param arg1 Node that produces the tensor to normalize
/// \param arg2 Node that produces ground truth lables for the input
/// \param soft_label flag indicating whether to interpretate the given labels as
/// soft
/// labels
/// \param ignore_index Specifies a target value that is ignored and does not
/// contribute
/// to the input gradient Only valid if soft_label is set to False
SoftmaxCrossEntropy(const Output<Node>& arg1,
const Output<Node>& arg2,
bool soft_label = false,
int64_t ignore_index = -100);
virtual NodeVector decompose_op() const override;
void pre_validate_and_infer_types() override;
virtual std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
bool get_soft_label() const { return m_soft_label; }
int64_t get_ignore_index() const { return m_ignore_index; }
private:
bool m_soft_label;
int64_t m_ignore_index;
};
}
using v0::SoftmaxCrossEntropy;
} // namespace op
} // namespace ngraph

View File

@ -1,17 +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 "ngraph/op/split.hpp"

View File

@ -57,12 +57,9 @@ NGRAPH_OP(Convolution, ngraph::op::v0, 0)
NGRAPH_OP(Convolution, ngraph::op::v1, 1)
NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v0, 0)
NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v1, 1)
NGRAPH_OP(ConvolutionBias, ngraph::op::v0, 0)
NGRAPH_OP(ConvolutionBiasAdd, ngraph::op::v0, 0)
NGRAPH_OP(Cos, ngraph::op::v0, 0)
NGRAPH_OP(Cosh, ngraph::op::v0, 0)
NGRAPH_OP(CropAndResize, ngraph::op::v0, 0)
NGRAPH_OP(CrossEntropy, ngraph::op::v0, 0)
NGRAPH_OP(CumSum, ngraph::op::v0, 0)
NGRAPH_OP(DeformableConvolution, ngraph::op::v1, 1)
NGRAPH_OP(DeformablePSROIPooling, ngraph::op::v1, 1)
@ -92,7 +89,6 @@ NGRAPH_OP(Gather, ngraph::op::v1, 1)
NGRAPH_OP(GatherND, ngraph::op::v0, 0)
NGRAPH_OP(GatherTree, ngraph::op::v1, 1)
NGRAPH_OP(Gelu, ngraph::op::v0, 0)
NGRAPH_OP(Gemm, ngraph::op::v0, 0)
NGRAPH_OP(GetOutputElement, ngraph::op::v0, 0)
NGRAPH_OP(Greater, ngraph::op::v0, 0)
NGRAPH_OP(Greater, ngraph::op::v1, 1)
@ -108,7 +104,6 @@ NGRAPH_OP(Interpolate, ngraph::op::v3, 3)
NGRAPH_OP(LRN, ngraph::op::v0, 0)
NGRAPH_OP(LSTMCell, ngraph::op::v0, 0)
NGRAPH_OP(LSTMSequence, ngraph::op::v0, 0)
NGRAPH_OP(LayerNorm, ngraph::op::v0, 0)
NGRAPH_OP(Less, ngraph::op::v0, 0)
NGRAPH_OP(Less, ngraph::op::v1, 1)
NGRAPH_OP(LessEq, ngraph::op::v0, 0)
@ -145,7 +140,6 @@ NGRAPH_OP(PSROIPooling, ngraph::op::v0, 0)
NGRAPH_OP(Pad, ngraph::op::v0, 0)
NGRAPH_OP(Pad, ngraph::op::v1, 1)
NGRAPH_OP(Parameter, ngraph::op::v0, 0)
NGRAPH_OP(PartialSlice, ngraph::op::v0, 0)
NGRAPH_OP(Passthrough, ngraph::op::v0, 0)
NGRAPH_OP(Power, ngraph::op::v0, 0)
NGRAPH_OP(Power, ngraph::op::v1, 1)
@ -179,7 +173,6 @@ NGRAPH_OP(Reverse, ngraph::op::v1, 1)
NGRAPH_OP(ReverseSequence, ngraph::op::v0, 0)
NGRAPH_OP(Round, ngraph::op::v0, 0)
NGRAPH_OP(ROIAlign, ngraph::op::v3, 3)
NGRAPH_OP(ScaleShift, ngraph::op::v0, 0)
NGRAPH_OP(ScatterElementsUpdate, ngraph::op::v3, 3)
NGRAPH_OP(ScatterUpdate, ngraph::op::v3, 3)
NGRAPH_OP(Select, ngraph::op::v0, 0)
@ -196,7 +189,6 @@ NGRAPH_OP(Sinh, ngraph::op::v0, 0)
NGRAPH_OP(Slice, ngraph::op::v0, 0)
NGRAPH_OP(Softmax, ngraph::op::v0, 0)
NGRAPH_OP(Softmax, ngraph::op::v1, 1)
NGRAPH_OP(SoftmaxCrossEntropy, ngraph::op::v0, 0)
NGRAPH_OP(SpaceToBatch, ngraph::op::v1, 1)
NGRAPH_OP(SpaceToDepth, ngraph::op::v0, 0)
NGRAPH_OP(Split, ngraph::op::v1, 1)
@ -204,7 +196,6 @@ NGRAPH_OP(Split, ngraph::op::v0, 0)
NGRAPH_OP(Sqrt, ngraph::op::v0, 0)
NGRAPH_OP(SquaredDifference, ngraph::op::v0, 0)
NGRAPH_OP(Squeeze, ngraph::op::v0, 0)
NGRAPH_OP(Stack, ngraph::op::v0, 0)
NGRAPH_OP(StopGradient, ngraph::op::v0, 0)
NGRAPH_OP(StridedSlice, ngraph::op::v1, 1)
NGRAPH_OP(Subtract, ngraph::op::v0, 0)

View File

@ -65,34 +65,26 @@
#include "ngraph/op/floor_mod.hpp"
#include "ngraph/op/fused/batch_to_space.hpp"
#include "ngraph/op/fused/clamp.hpp"
#include "ngraph/op/fused/conv_fused.hpp"
#include "ngraph/op/fused/crossentropy.hpp"
#include "ngraph/op/fused/depth_to_space.hpp"
#include "ngraph/op/fused/fake_quantize.hpp"
#include "ngraph/op/fused/gelu.hpp"
#include "ngraph/op/fused/gemm.hpp"
#include "ngraph/op/fused/grn.hpp"
#include "ngraph/op/fused/gru_cell.hpp"
#include "ngraph/op/fused/hard_sigmoid.hpp"
#include "ngraph/op/fused/layer_norm.hpp"
#include "ngraph/op/fused/lstm_cell.hpp"
#include "ngraph/op/fused/lstm_sequence.hpp"
#include "ngraph/op/fused/matmul.hpp"
#include "ngraph/op/fused/mod.hpp"
#include "ngraph/op/fused/mvn.hpp"
#include "ngraph/op/fused/normalize_l2.hpp"
#include "ngraph/op/fused/partial_slice.hpp"
#include "ngraph/op/fused/prelu.hpp"
#include "ngraph/op/fused/rnn_cell.hpp"
#include "ngraph/op/fused/scale_shift.hpp"
#include "ngraph/op/fused/selu.hpp"
#include "ngraph/op/fused/shuffle_channels.hpp"
#include "ngraph/op/fused/softmax_crossentropy.hpp"
#include "ngraph/op/fused/space_to_batch.hpp"
#include "ngraph/op/fused/space_to_depth.hpp"
#include "ngraph/op/fused/squared_difference.hpp"
#include "ngraph/op/fused/squeeze.hpp"
#include "ngraph/op/fused/stack.hpp"
#include "ngraph/op/fused/unsqueeze.hpp"
#include "ngraph/op/gather.hpp"
#include "ngraph/op/gather_nd.hpp"

View File

@ -29,8 +29,6 @@
#include "ngraph/op/convolution.hpp"
#include "ngraph/op/divide.hpp"
#include "ngraph/op/exp.hpp"
#include "ngraph/op/fused/conv_fused.hpp"
#include "ngraph/op/fused/softmax_crossentropy.hpp"
#include "ngraph/op/log.hpp"
#include "ngraph/op/max.hpp"
#include "ngraph/op/max_pool.hpp"
@ -62,39 +60,6 @@ static shared_ptr<Node> construct_constant_node(int n)
return op::Constant::create(element::f32, Shape{}, {n});
}
void pass::CoreFusion::construct_softmax_cross_entropy_fprop()
{
auto param_1 = std::make_shared<pattern::op::Label>(element::f32, Shape{41, 37});
auto softmax = std::make_shared<ngraph::op::Softmax>(param_1, AxisSet{1});
// parameter with one-hot encoded values
auto param_2 = std::make_shared<pattern::op::Label>(element::f32, Shape{41, 37});
auto log = std::make_shared<ngraph::op::Log>(softmax);
auto multiply = std::make_shared<ngraph::op::Multiply>(param_2, log);
auto reduction_axes = ngraph::op::Constant::create(element::i64, Shape{}, {1});
auto reduction_axes_label = std::make_shared<pattern::op::Label>(reduction_axes);
auto sum = std::make_shared<ngraph::op::Sum>(multiply, reduction_axes_label);
auto negative = std::make_shared<ngraph::op::Negative>(sum);
auto reshape = std::make_shared<ngraph::op::Reshape>(negative, AxisVector{0}, Shape{41, 1});
auto callback = [reduction_axes_label, param_1, param_2](pattern::Matcher& m) {
NGRAPH_DEBUG << "In a callback for construct_softmax_cross_entropy_fprop against "
<< m.get_match_root()->get_name();
auto pattern_map = m.get_pattern_map();
auto input_to_normalize = pattern_map[param_1];
auto labels = pattern_map[param_2];
auto softmax_crossentropy =
std::make_shared<ngraph::op::SoftmaxCrossEntropy>(input_to_normalize, labels, true);
ngraph::replace_node(m.get_match_root(), softmax_crossentropy);
return true;
};
auto m = std::make_shared<pattern::Matcher>(reshape, "CoreFusion.SoftmaxCrossEntropy");
this->add_matcher(m, callback);
}
void pass::CoreFusion::construct_relu()
{
auto iconst0 = construct_constant_node(0);
@ -755,142 +720,3 @@ void pass::CoreFusion::construct_zero_padded_conv()
auto m = std::make_shared<ngraph::pattern::Matcher>(conv_label, "CoreFusion.ZeroPaddedConv");
this->add_matcher(m, callback);
}
void pass::CoreFusion::construct_conv_bias()
{
Shape shape{2, 2, 1, 1};
auto data_batch = make_shared<pattern::op::Label>(element::f32, shape);
auto filters = make_shared<pattern::op::Label>(element::f32, shape);
auto pbias = make_shared<pattern::op::Label>(element::f32, Shape{});
auto pbcast = make_shared<op::Broadcast>(pbias, shape, AxisSet{0, 1, 2, 3});
auto pbcast_label = make_shared<pattern::op::Label>(pbcast, nullptr, NodeVector{pbcast});
auto reshape_pred = [](shared_ptr<Node> node) -> bool {
if (auto reshape = as_type_ptr<op::Reshape>(node))
{
auto ishape = reshape->get_input_shape(0);
auto oshape = reshape->get_shape();
// Callback will check that broadcast happens along channel (1) dimension.
// Reshape should not alter that
if (!reshape->get_is_transpose() && ishape.size() > 1 && oshape.size() > 1 &&
ishape[0] == oshape[0] && ishape[1] == oshape[1])
{
return true;
}
}
return false;
};
auto pskip = make_shared<pattern::op::Skip>(pbcast_label, reshape_pred);
auto pconv1 = make_shared<op::Convolution>(data_batch,
filters,
Strides{1, 1},
Strides{1, 1},
CoordinateDiff{0, 0},
CoordinateDiff{0, 0},
Strides{1, 1});
auto p_conv_bias = pskip + pconv1;
auto callback = [pbcast_label](pattern::Matcher& m) {
NGRAPH_DEBUG << "In callback for construct_conv_bias against node = "
<< m.get_match_root()->get_name();
auto pattern_map = m.get_pattern_map();
auto conv_m =
as_type_ptr<op::Convolution>(m.get_match_root()->input_value(0).get_node_shared_ptr());
if (conv_m == nullptr)
{
conv_m = static_pointer_cast<op::Convolution>(
m.get_match_root()->input_value(1).get_node_shared_ptr());
}
if (conv_m->get_shape().size() > 5 || conv_m->get_element_type() != element::f32)
{
// Most backends are unlikely to efficiently support these convolutions. Skip fusion
return false;
}
auto bcast_m = static_pointer_cast<op::Broadcast>(pattern_map[pbcast_label]);
// Except for the 2nd axis (channel dimension), we should either be broadcasting
// to it or the dimension size should be 1.
auto bcast_axes = bcast_m->get_broadcast_axes();
for (size_t i = 0; i < bcast_m->get_shape().size(); i++)
{
if (i != 1 && bcast_axes.find(i) == bcast_axes.end() && bcast_m->get_shape()[i] != 1)
{
return false;
}
}
auto bias = bcast_m->input_value(0).get_node_shared_ptr();
if (bias->get_shape().size() > 1)
{
NGRAPH_DEBUG << "mpattern = " << m.get_match_root()->get_name()
<< "conv_bias bias shape != 1, requires reshape to match filter count.";
auto order = get_default_order(bias->get_shape());
auto bias_reshape =
make_shared<op::Reshape>(bias, order, Shape{conv_m->get_input_shape(1)[0]});
auto conv_bias = shared_ptr<Node>(new op::ConvolutionBias(conv_m, bias_reshape));
replace_node(m.get_match_root(), conv_bias);
}
else
{
auto conv_bias = shared_ptr<Node>(new op::ConvolutionBias(conv_m, bias));
replace_node(m.get_match_root(), conv_bias);
}
return true;
};
auto m = std::make_shared<ngraph::pattern::Matcher>(p_conv_bias, "CoreFusion.ConvBias");
this->add_matcher(m, callback, PassProperty::REQUIRE_STATIC_SHAPE);
}
void pass::CoreFusion::construct_conv_bias_add()
{
Shape shape{2, 2, 1, 1};
auto data_batch = make_shared<pattern::op::Label>(element::f32, shape);
auto filters = make_shared<pattern::op::Label>(element::f32, shape);
auto bias = make_shared<pattern::op::Label>(element::f32, Shape{shape[0]});
auto pconv = make_shared<op::ConvolutionBias>(data_batch,
filters,
bias,
Strides{1, 1},
Strides{1, 1},
CoordinateDiff{0, 0},
CoordinateDiff{0, 0},
Strides{1, 1});
auto add_input = make_shared<pattern::op::Label>(element::f32, pconv->get_shape());
auto padd = make_shared<op::Add>(add_input, pconv);
auto callback = [data_batch, filters](pattern::Matcher& m) {
NGRAPH_DEBUG << "In a callback for construct_conv_sum against "
<< m.get_match_root()->get_name();
auto add_m = m.get_match_root();
auto pattern_map = m.get_pattern_map();
auto conv_m = as_type_ptr<op::ConvolutionBias>(add_m->input_value(1).get_node_shared_ptr());
auto add_input_m = add_m->input_value(0).get_node_shared_ptr();
if (!conv_m)
{
conv_m = static_pointer_cast<op::ConvolutionBias>(
add_m->input_value(0).get_node_shared_ptr());
add_input_m = add_m->input_value(1).get_node_shared_ptr();
}
if (get_user_count(conv_m.get()) > 1)
{
NGRAPH_DEBUG << "Convolution has more than one user";
return false;
}
auto conv_add = shared_ptr<Node>(new op::ConvolutionBiasAdd(conv_m, add_input_m, false));
replace_node(m.get_match_root(), conv_add);
return true;
};
auto m = std::make_shared<pattern::Matcher>(padd, "CoreFusion.ConvBiasAdd");
this->add_matcher(m, callback, all_pass_property_off);
}

View File

@ -42,16 +42,6 @@ public:
construct_reshape_softmax_reshape();
construct_zero_padded_reshaped_conv();
construct_zero_padded_conv();
construct_softmax_cross_entropy_fprop();
}
// Patterns under FOP_FUSIONS create ops (FusedOps) that might not
// be all supported by certain backends. In such a case, backends
// can register a FusedOpDecomposition pass after CoreFusion that will
// selectively decompose the unsupported ops back to the Core opset
if (fusions.is_set(FusionType::FOP_FUSIONS))
{
construct_conv_bias();
construct_conv_bias_add();
}
}
void construct_relu();
@ -62,7 +52,4 @@ public:
void construct_reshape_softmax_reshape();
void construct_zero_padded_reshaped_conv();
void construct_zero_padded_conv();
void construct_conv_bias();
void construct_conv_bias_add();
void construct_softmax_cross_entropy_fprop();
};

View File

@ -1104,47 +1104,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
data_dilation_strides_forward);
break;
}
case OP_TYPEID::ConvolutionBias:
{
auto window_movement_strides =
node_js.at("window_movement_strides").get<vector<size_t>>();
auto window_dilation_strides =
node_js.at("window_dilation_strides").get<vector<size_t>>();
auto padding_below = node_js.at("padding_below").get<vector<std::ptrdiff_t>>();
auto padding_above = node_js.at("padding_above").get<vector<std::ptrdiff_t>>();
auto data_dilation_strides = node_js.at("data_dilation_strides").get<vector<size_t>>();
node = make_shared<op::ConvolutionBias>(args[0],
args[1],
args[2],
window_movement_strides,
window_dilation_strides,
padding_below,
padding_above,
data_dilation_strides);
break;
}
case OP_TYPEID::ConvolutionBiasAdd:
{
auto window_movement_strides =
node_js.at("window_movement_strides").get<vector<size_t>>();
auto window_dilation_strides =
node_js.at("window_dilation_strides").get<vector<size_t>>();
auto padding_below = node_js.at("padding_below").get<vector<std::ptrdiff_t>>();
auto padding_above = node_js.at("padding_above").get<vector<std::ptrdiff_t>>();
auto data_dilation_strides = node_js.at("data_dilation_strides").get<vector<size_t>>();
node = make_shared<op::ConvolutionBiasAdd>(args[0],
args[1],
args[2],
args[3],
window_movement_strides,
window_dilation_strides,
padding_below,
padding_above,
data_dilation_strides);
break;
}
case OP_TYPEID::Cos:
{
node = make_shared<op::Cos>(args[0]);
@ -1162,13 +1121,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
node = make_shared<op::CumSum>(args[0], args[1], exclusive, reverse);
break;
}
case OP_TYPEID::CrossEntropy:
{
auto soft_label = node_js.at("soft_label");
auto ignore_index = node_js.at("ignore_index");
node = make_shared<op::CrossEntropy>(args[0], args[1], soft_label, ignore_index);
break;
}
case OP_TYPEID::CropAndResize:
{
auto resize_method =
@ -1295,15 +1247,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
node = make_shared<op::Gelu>(args[0]);
break;
}
case OP_TYPEID::Gemm:
{
auto alpha = node_js.at("alpha").get<double>();
auto beta = node_js.at("beta").get<double>();
auto transA = node_js.at("transA").get<bool>();
auto transB = node_js.at("transB").get<bool>();
node = make_shared<op::Gemm>(args[0], args[1], args[2], alpha, beta, transA, transB);
break;
}
case OP_TYPEID::GetOutputElement:
{
node = make_shared<op::GetOutputElement>(
@ -1390,23 +1333,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
node = make_shared<op::HardSigmoid>(args[0], args[1], args[2]);
break;
}
case OP_TYPEID::LayerNorm:
{
auto keep_stats = node_js.at("keep_stats").get<bool>();
auto use_affine = node_js.at("use_affine").get<bool>();
auto epsilon = node_js.at("epsilon").get<double>();
auto begin_norm_axis = node_js.at("begin_norm_axis").get<int64_t>();
if (use_affine)
{
node = make_shared<op::LayerNorm>(
args[0], args[1], args[2], keep_stats, begin_norm_axis, epsilon);
}
else
{
node = make_shared<op::LayerNorm>(args[0], keep_stats, begin_norm_axis, epsilon);
}
break;
}
case OP_TYPEID::Less:
{
node = make_shared<op::v0::Less>(
@ -1678,16 +1604,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
node = make_shared<op::Parameter>(element_type, read_partial_shape(shape), cacheable);
break;
}
case OP_TYPEID::PartialSlice:
{
auto axes = node_js.at("axes").get<vector<size_t>>();
auto lower_bounds = node_js.at("lower_bounds").get<vector<int64_t>>();
auto upper_bounds = node_js.at("upper_bounds").get<vector<int64_t>>();
auto decrease_axes = node_js.at("decrease_axes").get<vector<size_t>>();
node = make_shared<op::PartialSlice>(
args[0], axes, lower_bounds, upper_bounds, decrease_axes);
break;
}
case OP_TYPEID::Passthrough:
{
std::vector<json> outputs_js = node_js.at("output_shapes");
@ -1908,22 +1824,11 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
node = make_shared<op::Round>(args[0]);
break;
}
case OP_TYPEID::ScaleShift:
{
node = make_shared<op::ScaleShift>(args[0], args[1], args[2]);
break;
}
case OP_TYPEID::Select:
{
node = make_shared<op::Select>(args[0], args[1], args[2]);
break;
}
case OP_TYPEID::Stack:
{
auto axis = node_js.at("axis").get<size_t>();
node = make_shared<op::Stack>(static_cast<OutputVector>(args), axis);
break;
}
case OP_TYPEID::Selu:
{
node = make_shared<op::Selu>(args[0], args[1], args[2]);
@ -1989,13 +1894,6 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
break;
}
case OP_TYPEID::SoftmaxCrossEntropy:
{
auto soft_label = node_js.at("soft_label");
auto ignore_index = node_js.at("ignore_index");
node = make_shared<op::SoftmaxCrossEntropy>(args[0], args[1], soft_label, ignore_index);
break;
}
case OP_TYPEID::SpaceToDepth:
{
auto block_size = node_js.at("block_size").get<size_t>();
@ -2409,26 +2307,6 @@ json JSONSerializer::serialize_node(const Node& n)
node["data_dilation_strides_forward"] = tmp->get_data_dilation_strides_forward();
break;
}
case OP_TYPEID::ConvolutionBias:
{
auto tmp = static_cast<const op::ConvolutionBias*>(&n);
node["window_movement_strides"] = tmp->get_window_movement_strides();
node["window_dilation_strides"] = tmp->get_window_dilation_strides();
node["padding_below"] = tmp->get_padding_below();
node["padding_above"] = tmp->get_padding_above();
node["data_dilation_strides"] = tmp->get_data_dilation_strides();
break;
}
case OP_TYPEID::ConvolutionBiasAdd:
{
auto tmp = static_cast<const op::ConvolutionBiasAdd*>(&n);
node["window_movement_strides"] = tmp->get_window_movement_strides();
node["window_dilation_strides"] = tmp->get_window_dilation_strides();
node["padding_below"] = tmp->get_padding_below();
node["padding_above"] = tmp->get_padding_above();
node["data_dilation_strides"] = tmp->get_data_dilation_strides();
break;
}
case OP_TYPEID::Cos: { break;
}
case OP_TYPEID::Cosh: { break;
@ -2440,13 +2318,6 @@ json JSONSerializer::serialize_node(const Node& n)
node["reverse"] = tmp->is_reverse();
break;
}
case OP_TYPEID::CrossEntropy:
{
auto tmp = static_cast<const op::CrossEntropy*>(&n);
node["soft_label"] = tmp->get_soft_label();
node["ignore_index"] = tmp->get_ignore_index();
break;
}
case OP_TYPEID::CropAndResize:
{
auto tmp = static_cast<const op::CropAndResize*>(&n);
@ -2557,15 +2428,6 @@ json JSONSerializer::serialize_node(const Node& n)
}
case OP_TYPEID::Gelu: { break;
}
case OP_TYPEID::Gemm:
{
auto tmp = static_cast<const op::Gemm*>(&n);
node["alpha"] = tmp->get_alpha();
node["beta"] = tmp->get_beta();
node["transA"] = tmp->get_transA();
node["transB"] = tmp->get_transB();
break;
}
case OP_TYPEID::Greater:
{
const op::util::BinaryElementwiseComparison* tmp = nullptr;
@ -2619,15 +2481,6 @@ json JSONSerializer::serialize_node(const Node& n)
}
case OP_TYPEID::HardSigmoid: { break;
}
case OP_TYPEID::LayerNorm:
{
auto tmp = static_cast<const op::LayerNorm*>(&n);
node["keep_stats"] = tmp->get_keep_stats();
node["use_affine"] = tmp->get_use_affine();
node["epsilon"] = tmp->get_epsilon();
node["begin_norm_axis"] = tmp->get_begin_norm_axis();
break;
}
case OP_TYPEID::Less:
{
const op::util::BinaryElementwiseComparison* tmp = nullptr;
@ -2801,15 +2654,6 @@ json JSONSerializer::serialize_node(const Node& n)
node["element_type"] = write_element_type(tmp->get_element_type());
break;
}
case OP_TYPEID::PartialSlice:
{
auto tmp = dynamic_cast<const op::PartialSlice*>(&n);
node["axes"] = tmp->get_axes();
node["lower_bounds"] = tmp->get_lower_bounds();
node["upper_bounds"] = tmp->get_upper_bounds();
node["decrease_axes"] = tmp->get_decrease_axes();
break;
}
case OP_TYPEID::Passthrough:
{
auto tmp = static_cast<const op::Passthrough*>(&n);
@ -2931,8 +2775,6 @@ json JSONSerializer::serialize_node(const Node& n)
node["activations_beta"] = tmp->get_activations_beta();
break;
}
case OP_TYPEID::ScaleShift: { break;
}
case OP_TYPEID::Select: { break;
}
case OP_TYPEID::Selu: { break;
@ -3012,21 +2854,8 @@ json JSONSerializer::serialize_node(const Node& n)
node["reduction_axes"] = tmp->get_reduction_axes();
break;
}
case OP_TYPEID::Stack:
{
auto tmp = static_cast<const op::Stack*>(&n);
node["axis"] = tmp->get_axis();
break;
}
case OP_TYPEID::Softmax: { break;
}
case OP_TYPEID::SoftmaxCrossEntropy:
{
auto tmp = static_cast<const op::SoftmaxCrossEntropy*>(&n);
node["soft_label"] = tmp->get_soft_label();
node["ignore_index"] = tmp->get_ignore_index();
break;
}
case OP_TYPEID::Tan: { break;
}
case OP_TYPEID::Tanh: { break;

View File

@ -120,7 +120,6 @@ set(SRC
type_prop/constant.cpp
type_prop/convert.cpp
type_prop/convolution.cpp
type_prop/convolution_bias.cpp
type_prop/crop_and_resize.cpp
type_prop/deformable_psroi_pooling.cpp
type_prop/depth_to_space.cpp
@ -138,14 +137,12 @@ set(SRC
type_prop/gather.cpp
type_prop/gather_nd.cpp
type_prop/gather_tree.cpp
type_prop/gemm.cpp
type_prop/get_output_element.cpp
type_prop/grn.cpp
type_prop/group_convolution.cpp
type_prop/group_convolution_backprop_data.cpp
type_prop/gru_cell.cpp
type_prop/hard_sigmoid.cpp
type_prop/layer_norm.cpp
type_prop/lrn.cpp
type_prop/lstm_cell.cpp
type_prop/lstm_sequence.cpp
@ -171,7 +168,6 @@ set(SRC
type_prop/reverse_sequence.cpp
type_prop/roi_align.cpp
type_prop/rnn_cell.cpp
type_prop/scale_shift.cpp
type_prop/scatter_elements_update.cpp
type_prop/scatter_nd_update.cpp
type_prop/scatter_update.cpp
@ -309,7 +305,6 @@ set(MULTI_TEST_SRC
backend/gather.in.cpp
backend/gelu.in.cpp
backend/group_convolution.in.cpp
backend/layer_norm.in.cpp
backend/log.in.cpp
backend/logical_or.in.cpp
backend/logical_xor.in.cpp
@ -330,7 +325,6 @@ set(MULTI_TEST_SRC
backend/one_hot.in.cpp
backend/pad.in.cpp
backend/parameter_as_output.in.cpp
backend/partial_slice.in.cpp
backend/power.in.cpp
backend/product.in.cpp
backend/quantize_dequantize.in.cpp

View File

@ -49,94 +49,6 @@ static string s_manifest = "${MANIFEST}";
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
NGRAPH_TEST(${BACKEND_NAME}, stack_matrix_rowise)
{
Shape shape_a{2, 2};
auto A = make_shared<op::Parameter>(element::f32, shape_a);
Shape shape_b{2, 2};
auto B = make_shared<op::Parameter>(element::f32, shape_b);
Shape shape_c{2, 2};
auto C = make_shared<op::Parameter>(element::f32, shape_c);
Shape shape_r{3, 2, 2};
auto f = make_shared<Function>(make_shared<op::Stack>(NodeVector{A, B, C}, 0),
ParameterVector{A, B, C});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, shape_a);
copy_data(a, vector<float>{2, 4, 8, 8});
auto b = backend->create_tensor(element::f32, shape_b);
copy_data(b, vector<float>{1, 2, 4, 8});
auto c = backend->create_tensor(element::f32, shape_c);
copy_data(c, vector<float>{2, 3, 5, 7});
auto result = backend->create_tensor(element::f32, shape_r);
auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b, c});
EXPECT_TRUE(test::all_close_f((vector<float>{2, 4, 8, 8, 1, 2, 4, 8, 2, 3, 5, 7}),
read_vector<float>(result),
MIN_FLOAT_TOLERANCE_BITS));
}
NGRAPH_TEST(${BACKEND_NAME}, stack_matrix_colwise)
{
Shape shape_a{2, 2};
auto A = make_shared<op::Parameter>(element::f32, shape_a);
Shape shape_b{2, 2};
auto B = make_shared<op::Parameter>(element::f32, shape_b);
Shape shape_c{2, 2};
auto C = make_shared<op::Parameter>(element::f32, shape_c);
Shape shape_r{2, 3, 2};
auto f = make_shared<Function>(make_shared<op::Stack>(NodeVector{A, B, C}, 1),
ParameterVector{A, B, C});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, shape_a);
copy_data(a, vector<float>{2, 4, 8, 8});
auto b = backend->create_tensor(element::f32, shape_b);
copy_data(b, vector<float>{1, 2, 4, 8});
auto c = backend->create_tensor(element::f32, shape_c);
copy_data(c, vector<float>{2, 3, 5, 7});
auto result = backend->create_tensor(element::f32, shape_r);
auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b, c});
EXPECT_TRUE(test::all_close_f((vector<float>{2, 4, 1, 2, 2, 3, 8, 8, 4, 8, 5, 7}),
read_vector<float>(result),
MIN_FLOAT_TOLERANCE_BITS));
}
NGRAPH_TEST(${BACKEND_NAME}, stack_negative_axis)
{
auto pshape_a = PartialShape::dynamic();
auto A = make_shared<op::Parameter>(element::f32, pshape_a);
auto pshape_b = PartialShape::dynamic();
auto B = make_shared<op::Parameter>(element::f32, pshape_b);
auto pshape_c = PartialShape::dynamic();
auto C = make_shared<op::Parameter>(element::f32, pshape_c);
auto pshape_r = PartialShape::dynamic();
auto f = make_shared<Function>(make_shared<op::Stack>(NodeVector{A, B, C}, -1),
ParameterVector{A, B, C});
auto backend = runtime::Backend::create("${BACKEND_NAME}", true);
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, Shape{2, 2});
copy_data(a, vector<float>{2, 4, 8, 16});
auto b = backend->create_tensor(element::f32, Shape{2, 2});
copy_data(b, vector<float>{1, 2, 4, 8});
auto c = backend->create_tensor(element::f32, Shape{2, 2});
copy_data(c, vector<float>{2, 3, 5, 7});
auto result = backend->create_dynamic_tensor(element::f32, PartialShape::dynamic());
auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b, c});
ASSERT_EQ(result->get_shape(), (Shape{2, 2, 3}));
EXPECT_TRUE(test::all_close_f((vector<float>{2, 1, 2, 4, 2, 3, 8, 4, 5, 16, 8, 7}),
read_vector<float>(result)));
}
NGRAPH_TEST(${BACKEND_NAME}, elu)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 2});
@ -277,107 +189,6 @@ NGRAPH_TEST(${BACKEND_NAME}, prelu_negative_slope)
EXPECT_EQ(expected, read_vector<float>(result0));
}
NGRAPH_TEST(${BACKEND_NAME}, conv_bias_1d)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{1, 3, 2});
auto filters = make_shared<op::Parameter>(element::f32, Shape{2, 3, 1});
auto bias = make_shared<op::Parameter>(element::f32, Shape{2});
auto conv_bias = make_shared<op::ConvolutionBias>(data, filters, bias);
auto f0 = make_shared<Function>(NodeVector{conv_bias}, ParameterVector{data, filters, bias});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, Shape{1, 3, 2});
copy_data(a, vector<float>{1, 2, 3, 4, 5, 6});
auto b = backend->create_tensor(element::f32, Shape{2, 3, 1});
copy_data(b, vector<float>{1, 2, 3, 4, 5, 6});
auto c = backend->create_tensor(element::f32, Shape{2});
copy_data(c, vector<float>{1, 2});
auto result0 = backend->create_tensor(element::f32, conv_bias->get_shape());
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b, c});
vector<float> expected{23, 29, 51, 66};
EXPECT_EQ(expected, read_vector<float>(result0));
}
NGRAPH_TEST(${BACKEND_NAME}, conv_bias_2d)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{1, 3, 2, 2});
auto filters = make_shared<op::Parameter>(element::f32, Shape{2, 3, 1, 1});
auto bias = make_shared<op::Parameter>(element::f32, Shape{2});
auto conv_bias = make_shared<op::ConvolutionBias>(data, filters, bias);
auto f0 = make_shared<Function>(NodeVector{conv_bias}, ParameterVector{data, filters, bias});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, Shape{1, 3, 2, 2});
copy_data(a, vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
auto b = backend->create_tensor(element::f32, Shape{2, 3, 1, 1});
copy_data(b, vector<float>{1, 2, 3, 4, 5, 6});
auto c = backend->create_tensor(element::f32, Shape{2});
copy_data(c, vector<float>{1, 2});
auto result0 = backend->create_tensor(element::f32, conv_bias->get_shape());
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b, c});
vector<float> expected{39, 45, 51, 57, 85, 100, 115, 130};
EXPECT_EQ(expected, read_vector<float>(result0));
}
NGRAPH_TEST(${BACKEND_NAME}, conv_bias_3d)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{1, 3, 1, 2, 2});
auto filters = make_shared<op::Parameter>(element::f32, Shape{2, 3, 1, 1, 1});
auto bias = make_shared<op::Parameter>(element::f32, Shape{2});
auto conv_bias = make_shared<op::ConvolutionBias>(data, filters, bias);
auto f0 = make_shared<Function>(NodeVector{conv_bias}, ParameterVector{data, filters, bias});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, Shape{1, 3, 1, 2, 2});
copy_data(a, vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
auto b = backend->create_tensor(element::f32, Shape{2, 3, 1, 1, 1});
copy_data(b, vector<float>{1, 2, 3, 4, 5, 6});
auto c = backend->create_tensor(element::f32, Shape{2});
copy_data(c, vector<float>{1, 2});
auto result0 = backend->create_tensor(element::f32, conv_bias->get_shape());
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b, c});
vector<float> expected{39, 45, 51, 57, 85, 100, 115, 130};
EXPECT_EQ(expected, read_vector<float>(result0));
}
NGRAPH_TEST(${BACKEND_NAME}, conv_bias_add_2d)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{1, 3, 2, 2});
auto filters = make_shared<op::Parameter>(element::f32, Shape{2, 3, 1, 1});
auto bias = make_shared<op::Parameter>(element::f32, Shape{2});
auto add = make_shared<op::Parameter>(element::f32, Shape{1, 2, 2, 2});
auto conv_bias = make_shared<op::ConvolutionBias>(data, filters, bias);
auto conv_bias_add = make_shared<op::ConvolutionBiasAdd>(conv_bias, add);
auto f0 =
make_shared<Function>(NodeVector{conv_bias_add}, ParameterVector{data, filters, bias, add});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, Shape{1, 3, 2, 2});
copy_data(a, vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
auto b = backend->create_tensor(element::f32, Shape{2, 3, 1, 1});
copy_data(b, vector<float>{1, 2, 3, 4, 5, 6});
auto c = backend->create_tensor(element::f32, Shape{2});
copy_data(c, vector<float>{1, 2});
auto d = backend->create_tensor(element::f32, Shape{1, 2, 2, 2});
copy_data(d, vector<float>{1, 2, 3, 4, 5, 6, 7, 8});
auto result0 = backend->create_tensor(element::f32, conv_bias_add->get_shape());
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b, c, d});
vector<float> expected{40, 47, 54, 61, 90, 106, 122, 138};
EXPECT_EQ(expected, read_vector<float>(result0));
}
NGRAPH_TEST(${BACKEND_NAME}, group_conv)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{1, 4, 2, 2});
@ -964,107 +775,6 @@ NGRAPH_TEST(${BACKEND_NAME}, normalize_across_chw_4d_max_bias)
test_case.run(DEFAULT_FLOAT_TOLERANCE_BITS + 1);
}
NGRAPH_TEST(${BACKEND_NAME}, gemm)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto gemm_func = make_shared<op::Gemm>(A, B, C);
auto function = make_shared<Function>(NodeVector{gemm_func}, ParameterVector{A, B, C});
auto test_case = test::TestCase<TestEngine>(function);
// A
test_case.add_input<float>(vector<float>(18, 1));
// B
test_case.add_input<float>(vector<float>(24, 2));
// C
test_case.add_input<float>(vector<float>(12, 0));
// output
test_case.add_expected_output<float>(Shape{3, 4}, vector<float>(12, 12));
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, gemm_C)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto gemm_func = make_shared<op::Gemm>(A, B, C);
auto function = make_shared<Function>(NodeVector{gemm_func}, ParameterVector{A, B, C});
auto test_case = test::TestCase<TestEngine>(function);
// A
test_case.add_input<float>(vector<float>(18, 1));
// B
test_case.add_input<float>(vector<float>(24, 2));
// C
test_case.add_input<float>(vector<float>(12, 1));
// output
test_case.add_expected_output<float>(Shape{3, 4}, vector<float>(12, 13));
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, gemm_broadcast_input_C)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{});
auto gemm_func = make_shared<op::Gemm>(A, B, C, 0.5);
auto function = make_shared<Function>(NodeVector{gemm_func}, ParameterVector{A, B, C});
auto test_case = test::TestCase<TestEngine>(function);
// A
test_case.add_input<float>(vector<float>(18, 1));
// B
test_case.add_input<float>(vector<float>(24, 2));
// C
test_case.add_input<float>(vector<float>{1});
// output
test_case.add_expected_output<float>(Shape{3, 4}, vector<float>(12, 7));
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, gemm_broadcast_axes_0_input_C)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{1, 4});
auto gemm_func = make_shared<op::Gemm>(A, B, C, 0.5);
auto function = make_shared<Function>(NodeVector{gemm_func}, ParameterVector{A, B, C});
auto test_case = test::TestCase<TestEngine>(function);
// A
test_case.add_input<float>(vector<float>(18, 1));
// B
test_case.add_input<float>(vector<float>(24, 2));
// C
test_case.add_input<float>(vector<float>{1, 2, 3, 4});
// output
test_case.add_expected_output<float>(Shape{3, 4},
vector<float>{7, 8, 9, 10, 7, 8, 9, 10, 7, 8, 9, 10});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, gemm_broadcast_axes_1_input_C)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{3, 1});
auto gemm_func = make_shared<op::Gemm>(A, B, C, 0.5);
auto function = make_shared<Function>(NodeVector{gemm_func}, ParameterVector{A, B, C});
auto test_case = test::TestCase<TestEngine>(function);
// A
test_case.add_input<float>(vector<float>(18, 1));
// B
test_case.add_input<float>(vector<float>(24, 2));
// C
test_case.add_input<float>(vector<float>(3, 1));
// output
test_case.add_expected_output<float>(Shape{3, 4}, vector<float>(12, 7));
test_case.run();
}
namespace
{
template <typename T, test::TestCaseType tct = test::TestCaseType::STATIC>
@ -1844,48 +1554,6 @@ NGRAPH_TEST(${BACKEND_NAME}, unsqueeze)
test_case.add_expected_output<float>(Shape{4, 1, 1, 2}, data);
}
NGRAPH_TEST(${BACKEND_NAME}, scale_shift_no_broadcast)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto scale = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto shift = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto scale_shift_func = make_shared<op::ScaleShift>(data, scale, shift);
auto function =
make_shared<Function>(NodeVector{scale_shift_func}, ParameterVector{data, scale, shift});
auto test_case = test::TestCase<TestEngine>(function);
// Data
test_case.add_input<float>(vector<float>(18, 2));
// Scale
test_case.add_input<float>(vector<float>(18, 2));
// Shift
test_case.add_input<float>(vector<float>(18, 2));
// output
test_case.add_expected_output<float>(Shape{3, 6}, vector<float>(18, 6));
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, scale_shift)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto scale = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto shift = make_shared<op::Parameter>(element::f32, Shape{});
auto scale_shift_func = make_shared<op::ScaleShift>(data, scale, shift);
auto function =
make_shared<Function>(NodeVector{scale_shift_func}, ParameterVector{data, scale, shift});
auto test_case = test::TestCase<TestEngine>(function);
// Data
test_case.add_input<float>(vector<float>(18, 2));
// Scale
test_case.add_input<float>(vector<float>(18, 2));
// Shift
test_case.add_input<float>(vector<float>{2});
// output
test_case.add_expected_output<float>(Shape{3, 6}, vector<float>(18, 6));
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_simple)
{
const auto data = make_shared<op::Parameter>(element::i32, Shape{1, 15, 2, 2});
@ -2989,50 +2657,6 @@ NGRAPH_TEST(${BACKEND_NAME}, gru_cell_activation_function)
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, cross_entropy_with_soft_labels)
{
Shape tensor_shape{2, 4};
auto input = make_shared<op::Parameter>(element::f32, tensor_shape);
auto labels = make_shared<op::Parameter>(element::i32, Shape{2, 4});
auto cross_entropy = make_shared<op::CrossEntropy>(input, labels, true);
auto f0 = make_shared<Function>(NodeVector{cross_entropy}, ParameterVector{input, labels});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, tensor_shape);
copy_data(a, vector<float>{0.25f, 0.25f, 0.25f, 0.25f, 0.01f, 0.01f, 0.01f, 0.96f});
auto b = backend->create_tensor(element::i32, Shape{2, 4});
copy_data(b, vector<int32_t>{0, 0, 0, 1, 0, 0, 0, 1});
auto result0 = backend->create_tensor(element::f32, Shape{2, 1});
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b});
vector<float> expected{1.38629f, 0.040822f};
auto result = read_vector<float>(result0);
EXPECT_TRUE(test::all_close_f(result, expected, 23));
}
NGRAPH_TEST(${BACKEND_NAME}, cross_entropy_with_one_hot)
{
Shape tensor_shape{2, 4};
auto input = make_shared<op::Parameter>(element::f32, tensor_shape);
auto labels = make_shared<op::Parameter>(element::i32, Shape{2, 1});
auto cross_entropy = make_shared<op::CrossEntropy>(input, labels, false);
auto f0 = make_shared<Function>(NodeVector{cross_entropy}, ParameterVector{input, labels});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, tensor_shape);
copy_data(a, vector<float>{0.25f, 0.25f, 0.25f, 0.25f, 0.01f, 0.01f, 0.01f, 0.96f});
auto b = backend->create_tensor(element::i32, Shape{2, 1});
copy_data(b, vector<int32_t>{1, 1});
auto result0 = backend->create_tensor(element::f32, Shape{2, 1});
auto handle = backend->compile(f0);
handle->call_with_validate({result0}, {a, b});
vector<float> expected{1.38629f, 4.60517f};
auto result = read_vector<float>(result0);
EXPECT_TRUE(test::all_close_f(result, expected, 23));
}
NGRAPH_TEST(${BACKEND_NAME}, depth_to_space_space_to_depth_block_first)
{
auto backend = runtime::Backend::create("${BACKEND_NAME}");

View File

@ -30,61 +30,6 @@ using namespace ngraph;
static string s_manifest = "${MANIFEST}";
NGRAPH_TEST(${BACKEND_NAME}, quantized_convolution)
{
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<int8_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::i8, shape_b);
auto C = make_shared<op::Parameter>(element::f32, Shape{});
auto D = make_shared<op::Parameter>(element::f32, Shape{});
auto E = make_shared<op::Parameter>(element::f32, Shape{});
auto F = make_shared<op::Parameter>(element::f32, Shape{});
auto G = make_shared<op::Parameter>(element::f32, Shape{});
auto H = make_shared<op::Parameter>(element::f32, Shape{});
auto CV = ngraph::builder::QuantizedConvolutionBuilder(A,
B,
Strides{1, 1},
Strides{1, 1},
CoordinateDiff{1, 1},
CoordinateDiff{1, 1},
Strides{1, 1},
C,
D,
E,
F,
G,
H,
element::i8);
auto f = make_shared<Function>(NodeVector{CV}, ParameterVector{A, B, C, D, E, F, G, H});
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::i8, shape_b);
copy_data(b, b_data);
auto d = backend->create_tensor(element::f32, Shape{});
copy_data(d, vector<float>{0.0f});
auto e = backend->create_tensor(element::f32, Shape{});
copy_data(e, vector<float>{255.0f});
auto e_a = backend->create_tensor(element::f32, Shape{});
copy_data(e_a, vector<float>{-127.0f});
auto g = backend->create_tensor(element::f32, Shape{});
copy_data(g, vector<float>{127.0f});
auto h = backend->create_tensor(element::f32, Shape{});
copy_data(h, vector<float>{22.0f});
auto i = backend->create_tensor(element::f32, Shape{});
copy_data(i, vector<float>{90.0f});
auto result = backend->create_tensor(element::i8, shape_r);
auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b, d, e, e_a, g, h, i});
EXPECT_EQ((vector<int8_t>{31, 48, 42, 45, 54, 102, 127, 61, 47, 73, 61, 55}),
read_vector<int8_t>(result));
}
NGRAPH_TEST(${BACKEND_NAME}, quantized_conv_int32_output)
{
Shape shape_a{1, 1, 3, 4};

View File

@ -186,24 +186,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_ConvolutionBias()
{
op::ConvolutionBias node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_ConvolutionBiasAdd()
{
op::ConvolutionBiasAdd node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Cos()
{
op::Cos node;
@ -222,15 +204,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_CrossEntropy()
{
op::CrossEntropy node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_CropAndResize()
{
op::CropAndResize node;
@ -429,15 +402,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Gemm()
{
op::Gemm node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_GetOutputElement()
{
op::GetOutputElement node;
@ -501,15 +465,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_LayerNorm()
{
op::LayerNorm node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Less()
{
op::Less node;
@ -699,15 +654,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_PartialSlice()
{
op::PartialSlice node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Passthrough()
{
op::Passthrough node;
@ -861,15 +807,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_ScaleShift()
{
op::ScaleShift node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Select()
{
op::Select node;
@ -969,15 +906,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_SoftmaxCrossEntropy()
{
op::SoftmaxCrossEntropy node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_SpaceToDepth()
{
op::SpaceToDepth node;
@ -1032,15 +960,6 @@ namespace
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Stack()
{
op::Stack node;
EXPECT_FALSE(node.is_unary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_arithmetic());
EXPECT_FALSE(node.is_binary_elementwise_comparison());
EXPECT_FALSE(node.is_binary_elementwise_logical());
}
void op_is_Subtract()
{
op::Subtract node;

View File

@ -113,7 +113,6 @@ TEST(opset, check_opset1)
CHECK_OPSET(op::v1::Maximum, opset1::Maximum)
CHECK_OPSET(op::v1::MaxPool, opset1::MaxPool)
CHECK_OPSET(op::v1::Minimum, opset1::Minimum)
// TODO CHECK_OPSET(op::v0::Mod, opset1::Mod)
CHECK_OPSET(op::v1::Multiply, opset1::Multiply)
CHECK_OPSET(op::v0::Negative, opset1::Negative)
// TODO using op::v0::NonMaxSuppression

View File

@ -648,12 +648,6 @@ reshape_v1
dyn_convolution_backprop_data
dyn_convolution_backprop_filter
# Cannot cast ngraph node PartialSlice to CNNLayer!
partial_slice_static
partial_slice_partial_shape
partial_slice_unkown_rank
partial_slice_bprop_unkown_rank
# Pad Pad_524448 with not constant pad_value is not allowed
pad_exterior_1d
pad_negative_exterior_1d
@ -698,14 +692,6 @@ lrn_6D_across_2_axes
# std::exception
lrn_2d_across_outermost_axis
# Cannot cast ngraph node LayerNorm_664923 to CNNLayer!
layer_norm_affine_stats
# Cannot cast ngraph node LayerNormBackprop_669060 to CNNLayer!
layer_norm_bprop_affine_stats
layer_norm_bprop_affine
layer_norm_bprop_4d_input
# Cannot cast ngraph node GroupConvolutionBackpropFilters_686350 to CNNLayer!
dyn_group_convolution_backprop_filters
@ -730,22 +716,6 @@ gather_nd_batch_scalar_from_3d
gather_nd_batch_1d_from_3d
gather_nd_batch_2d_from_3d
# Cannot cast ngraph node Stack to CNNLayer!
stack_matrix_rowise
stack_matrix_colwise
stack_negative_axis
# Cannot cast ngraph node ConvolutionBias to CNNLayer!
conv_bias_1d
conv_bias_2d
conv_bias_3d
# Cannot cast ngraph node ConvolutionBiasBackpropFiltersBias to CNNLayer!
conv_bias_bprop_2d
# Cannot cast ngraph node ConvolutionBiasAdd to CNNLayer!
conv_bias_add_2d
# Unsupported primitive of type: SpaceToBatch
space_to_batch
@ -756,17 +726,6 @@ batch_to_space
normalize_across_1axis_5d
normalize_across_123axes_5d
# Cannot cast ngraph node Gemm to CNNLayer!
gemm
gemm_C
gemm_broadcast_input_C
gemm_broadcast_axes_0_input_C
gemm_broadcast_axes_1_input_C
# Cannot cast ngraph node ScaleShift to CNNLayer!
scale_shift_no_broadcast
scale_shift
# Cannot cast ngraph node ShuffleChannels to CNNLayer!
shuffle_channels_simple
shuffle_channels_negative_axis
@ -791,10 +750,6 @@ gru_cell_bias_clip
gru_cell_linear_before_reset
gru_cell_activation_function
# Cannot cast ngraph node CrossEntropy to CNNLayer!
cross_entropy_with_soft_labels
cross_entropy_with_one_hot
# Cannot cast ngraph node EmbeddingLookup to CNNLayer!
embedding_lookup_4x5_reverse
embedding_lookup_10x1_arbitrary

View File

@ -1236,38 +1236,29 @@ protected:
}
// Fused Ops are not supported in interpreter. They need to be decomposed before execution
case OP_TYPEID::ConvolutionBias:
case OP_TYPEID::ConvolutionBiasAdd:
case OP_TYPEID::CropAndResize:
case OP_TYPEID::CrossEntropy:
case OP_TYPEID::DepthToSpace:
case OP_TYPEID::FakeQuantize:
case OP_TYPEID::Gather:
case OP_TYPEID::Gelu:
case OP_TYPEID::Gemm:
case OP_TYPEID::GRN:
case OP_TYPEID::GroupConvolution:
case OP_TYPEID::GroupConvolutionBackpropData:
case OP_TYPEID::GRUCell:
case OP_TYPEID::HardSigmoid:
case OP_TYPEID::Interpolate:
case OP_TYPEID::LayerNorm:
case OP_TYPEID::LSTMCell:
case OP_TYPEID::LSTMSequence:
case OP_TYPEID::MVN:
case OP_TYPEID::NormalizeL2:
case OP_TYPEID::PartialSlice:
case OP_TYPEID::Passthrough:
case OP_TYPEID::PRelu:
case OP_TYPEID::RNNCell:
case OP_TYPEID::ScaleShift:
case OP_TYPEID::Selu:
case OP_TYPEID::ShuffleChannels:
case OP_TYPEID::SoftmaxCrossEntropy:
case OP_TYPEID::SpaceToDepth:
case OP_TYPEID::Split:
case OP_TYPEID::SquaredDifference:
case OP_TYPEID::Stack:
case OP_TYPEID::StopGradient:
case OP_TYPEID::TensorIterator:
case OP_TYPEID::Tile:

View File

@ -68,11 +68,8 @@ NGRAPH_OP(Constant, ngraph::op)
NGRAPH_OP(Convert, ngraph::op)
NGRAPH_OP(Convolution, ngraph::op)
NGRAPH_OP(ConvolutionBackpropData, ngraph::op)
NGRAPH_OP(ConvolutionBias, ngraph::op)
NGRAPH_OP(ConvolutionBiasAdd, ngraph::op)
NGRAPH_OP(Cos, ngraph::op)
NGRAPH_OP(Cosh, ngraph::op)
NGRAPH_OP(CrossEntropy, ngraph::op)
NGRAPH_OP(CropAndResize, ngraph::op)
NGRAPH_OP(CumSum, ngraph::op::v0)
NGRAPH_OP(DepthToSpace, ngraph::op)
@ -91,7 +88,6 @@ NGRAPH_OP(GRUCell, ngraph::op)
NGRAPH_OP(Gather, ngraph::op)
NGRAPH_OP(GatherND, ngraph::op)
NGRAPH_OP(Gelu, ngraph::op)
NGRAPH_OP(Gemm, ngraph::op)
NGRAPH_OP(GetOutputElement, ngraph::op)
NGRAPH_OP(Greater, ngraph::op)
NGRAPH_OP(GreaterEq, ngraph::op)
@ -99,7 +95,6 @@ NGRAPH_OP(GroupConvolution, ngraph::op)
NGRAPH_OP(GroupConvolutionBackpropData, ngraph::op)
NGRAPH_OP(HardSigmoid, ngraph::op)
NGRAPH_OP(Interpolate, ngraph::op)
NGRAPH_OP(LayerNorm, ngraph::op)
NGRAPH_OP(Less, ngraph::op)
NGRAPH_OP(LessEq, ngraph::op)
NGRAPH_OP(Log, ngraph::op)
@ -121,7 +116,6 @@ NGRAPH_OP(OneHot, ngraph::op)
NGRAPH_OP(Or, ngraph::op)
NGRAPH_OP(Pad, ngraph::op)
NGRAPH_OP(Parameter, ngraph::op)
NGRAPH_OP(PartialSlice, ngraph::op)
NGRAPH_OP(Passthrough, ngraph::op)
NGRAPH_OP(Power, ngraph::op)
NGRAPH_OP(PRelu, ngraph::op)
@ -139,7 +133,6 @@ NGRAPH_OP(Reverse, ngraph::op)
NGRAPH_OP(ReverseSequence, ngraph::op)
NGRAPH_OP(RNNCell, ngraph::op)
NGRAPH_OP(Round, ngraph::op)
NGRAPH_OP(ScaleShift, ngraph::op)
NGRAPH_OP(Select, ngraph::op)
NGRAPH_OP(Selu, ngraph::op)
NGRAPH_OP(Send, ngraph::op)
@ -151,14 +144,12 @@ NGRAPH_OP(Sin, ngraph::op)
NGRAPH_OP(Sinh, ngraph::op)
NGRAPH_OP(Slice, ngraph::op)
NGRAPH_OP(Softmax, ngraph::op)
NGRAPH_OP(SoftmaxCrossEntropy, ngraph::op)
NGRAPH_OP(SpaceToDepth, ngraph::op)
NGRAPH_OP(Split, ngraph::op)
NGRAPH_OP(Sqrt, ngraph::op)
NGRAPH_OP(SquaredDifference, ngraph::op)
NGRAPH_OP(Squeeze, ngraph::op)
NGRAPH_OP(StopGradient, ngraph::op)
NGRAPH_OP(Stack, ngraph::op)
NGRAPH_OP(Subtract, ngraph::op)
NGRAPH_OP(Sum, ngraph::op)
NGRAPH_OP(Tan, ngraph::op)

View File

@ -1,60 +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"
using namespace std;
using namespace ngraph;
TEST(type_prop, conv_bias_2d_deduce)
{
// Deduce type
auto param0 = make_shared<op::Parameter>(element::f32, Shape{64, 3, 100, 150});
auto param1 = make_shared<op::Parameter>(element::f32, Shape{128, 3, 10, 20});
auto param2 = make_shared<op::Parameter>(element::f32, Shape{128});
auto conv = make_shared<op::ConvolutionBias>(param0, param1, param2);
EXPECT_EQ(conv->get_element_type(), element::f32);
EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 91, 131}));
EXPECT_EQ(conv->get_window_movement_strides(), (Strides{1, 1}));
EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{1, 1}));
EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1}));
EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0}));
EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0}));
}
TEST(type_prop, conv_bias_add_2d_deduce)
{
// Deduce type
auto param0 = make_shared<op::Parameter>(element::f32, Shape{64, 3, 100, 150});
auto param1 = make_shared<op::Parameter>(element::f32, Shape{128, 3, 10, 20});
auto param2 = make_shared<op::Parameter>(element::f32, Shape{128});
auto param3 = make_shared<op::Parameter>(element::f32, Shape{64, 128, 91, 131});
auto conv = make_shared<op::ConvolutionBiasAdd>(param0,
param1,
param2,
param3,
Strides{1, 1},
Strides{1, 1},
CoordinateDiff{0, 0},
CoordinateDiff{0, 0},
Strides{1, 1});
EXPECT_EQ(conv->get_element_type(), element::f32);
EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 91, 131}));
}

View File

@ -1,42 +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"
using namespace std;
using namespace ngraph;
TEST(type_prop, gemm)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto gemm_func = make_shared<op::Gemm>(A, B, C);
EXPECT_EQ(gemm_func->get_element_type(), element::f32);
EXPECT_EQ(gemm_func->get_shape(), (Shape{3, 4}));
}
TEST(type_prop, gemm_broadcast_input_C)
{
auto A = make_shared<op::Parameter>(element::f32, Shape{3, 6});
auto B = make_shared<op::Parameter>(element::f32, Shape{6, 4});
auto C = make_shared<op::Parameter>(element::f32, Shape{});
auto gemm_func = make_shared<op::Gemm>(A, B, C);
EXPECT_EQ(gemm_func->get_element_type(), element::f32);
EXPECT_EQ(gemm_func->get_shape(), (Shape{3, 4}));
}

View File

@ -1,87 +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"
using namespace std;
using namespace ngraph;
TEST(type_prop, layer_norm_element_type)
{
auto data = make_shared<op::Parameter>(element::i32, Shape{2, 4});
auto scale = make_shared<op::Parameter>(element::f32, Shape{4});
auto bias = make_shared<op::Parameter>(element::f32, Shape{4});
try
{
auto ln = make_shared<op::LayerNorm>(data, scale, bias);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect element type";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("Argument element type must be f16, bf16, f32, f64 or dynamic"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}
TEST(type_prop, layer_norm_begin_norm_axis)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{2, 4});
auto scale = make_shared<op::Parameter>(element::f32, Shape{4});
auto bias = make_shared<op::Parameter>(element::f32, Shape{4});
try
{
auto ln = make_shared<op::LayerNorm>(data, scale, bias, false, 2);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect begin norm axis";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(error.what(), std::string("begin_norm_axis is out of range"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}
TEST(type_prop, layer_norm_affine_rank)
{
auto data = make_shared<op::Parameter>(element::f32, Shape{2, 4});
auto scale = make_shared<op::Parameter>(element::f32, Shape{2, 4});
auto bias = make_shared<op::Parameter>(element::f32, Shape{4});
try
{
auto ln = make_shared<op::LayerNorm>(data, scale, bias);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect affine ranks";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(error.what(), std::string("Scale and/or bias rank is incorrect"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}

View File

@ -1,42 +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"
using namespace std;
using namespace ngraph;
TEST(type_prop, scale_shift_no_broadcast)
{
auto data = make_shared<op::Parameter>(element::f64, Shape{3, 6});
auto scale = make_shared<op::Parameter>(element::f64, Shape{3, 6});
auto shift = make_shared<op::Parameter>(element::f64, Shape{3, 6});
auto scale_shift_func = make_shared<op::ScaleShift>(data, scale, shift);
EXPECT_EQ(scale_shift_func->get_element_type(), element::f64);
EXPECT_EQ(scale_shift_func->get_shape(), (Shape{3, 6}));
}
TEST(type_prop, scale_shift)
{
auto data = make_shared<op::Parameter>(element::f64, Shape{3, 6});
auto scale = make_shared<op::Parameter>(element::f64, Shape{3, 6});
auto shift = make_shared<op::Parameter>(element::f64, Shape{});
auto scale_shift_func = make_shared<op::ScaleShift>(data, scale, shift);
EXPECT_EQ(scale_shift_func->get_element_type(), element::f64);
EXPECT_EQ(scale_shift_func->get_shape(), (Shape{3, 6}));
}