Removed v0 fused operations (#1263)
This commit is contained in:
parent
dca2ee2bcc
commit
cc19e57a06
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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});
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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)};
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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))};
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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"
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -54,10 +54,5 @@ namespace ngraph
|
||||
AutoBroadcastSpec m_auto_broadcast;
|
||||
};
|
||||
}
|
||||
|
||||
namespace v0
|
||||
{
|
||||
using v1::Mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
@ -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"
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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}");
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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}));
|
||||
}
|
@ -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}));
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
@ -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}));
|
||||
}
|
Loading…
Reference in New Issue
Block a user