Removed constant folding for Tile op (#1595)
This commit is contained in:
1 parent
86fb108b00
commit
e4b411f027
14 files changed
+109
-150
No files matched your search
@@ -354,7 +354,7 @@ std::shared_ptr<ngraph::Node> V10Parser::createNode(const std::vector<ngraph::Ou
|
||||
std::make_shared<LayerCreator<ngraph::op::Squeeze>>("Squeeze"),
|
||||
std::make_shared<LayerCreator<ngraph::op::Tan>>("Tan"),
|
||||
std::make_shared<LayerCreator<ngraph::op::Tanh>>("TanH"),
|
||||
std::make_shared<LayerCreator<ngraph::op::Tile>>("Tile"),
|
||||
std::make_shared<LayerCreator<ngraph::op::v0::Tile>>("Tile"),
|
||||
std::make_shared<LayerCreator<ngraph::op::v1::TopK>>("TopK"),
|
||||
std::make_shared<LayerCreator<ngraph::op::TensorIterator>>("TensorIterator"),
|
||||
std::make_shared<LayerCreator<ngraph::op::Transpose>>("Transpose"),
|
||||
@@ -1232,11 +1232,11 @@ std::shared_ptr<ngraph::Node> V10Parser::LayerCreator<ngraph::op::Result>::creat
|
||||
|
||||
// Tile layer
|
||||
template <>
|
||||
std::shared_ptr<ngraph::Node> V10Parser::LayerCreator<ngraph::op::Tile>::createLayer(
|
||||
std::shared_ptr<ngraph::Node> V10Parser::LayerCreator<ngraph::op::v0::Tile>::createLayer(
|
||||
const ngraph::OutputVector& inputs, const pugi::xml_node& node, std::istream& binStream,
|
||||
const GenericLayerParams& layerParsePrms) {
|
||||
checkParameters(inputs, layerParsePrms, 2);
|
||||
return std::make_shared<ngraph::op::Tile>(inputs[0], inputs[1]);
|
||||
return std::make_shared<ngraph::op::v0::Tile>(inputs[0], inputs[1]);
|
||||
}
|
||||
|
||||
// StridedSlice layer
|
||||
|
||||
@@ -451,7 +451,6 @@ set (SRC
|
||||
pass/constant_folding_slice.cpp
|
||||
pass/constant_folding_split.cpp
|
||||
pass/constant_folding_variadic_split.cpp
|
||||
pass/constant_folding_tile.cpp
|
||||
pass/constant_folding.cpp
|
||||
pass/constant_folding.hpp
|
||||
pass/convert_fp32_to_fp16.hpp
|
||||
@@ -516,6 +515,8 @@ set (SRC
|
||||
runtime/reference/eval_helpers.hpp
|
||||
runtime/reference/reshape.cpp
|
||||
runtime/reference/reshape.hpp
|
||||
runtime/reference/tile.cpp
|
||||
runtime/reference/tile.hpp
|
||||
shape.cpp
|
||||
shape.hpp
|
||||
shape_util.cpp
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
#include "ngraph/op/tile.hpp"
|
||||
|
||||
#include "ngraph/op/constant.hpp"
|
||||
#include "ngraph/runtime/reference/tile.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
constexpr NodeTypeInfo op::Tile::type_info;
|
||||
constexpr NodeTypeInfo op::v0::Tile::type_info;
|
||||
|
||||
op::Tile::Tile(const Output<Node>& data, const Output<Node>& repeats)
|
||||
op::v0::Tile::Tile(const Output<Node>& data, const Output<Node>& repeats)
|
||||
: Op({data, repeats})
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
@@ -34,7 +35,7 @@ bool ngraph::op::v0::Tile::visit_attributes(AttributeVisitor& visitor)
|
||||
return true;
|
||||
}
|
||||
|
||||
void op::Tile::validate_and_infer_types()
|
||||
void op::v0::Tile::validate_and_infer_types()
|
||||
{
|
||||
auto arg_et = get_input_element_type(0);
|
||||
|
||||
@@ -88,8 +89,37 @@ void op::Tile::validate_and_infer_types()
|
||||
set_input_is_relevant_to_shape(1);
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::Tile::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
shared_ptr<Node> op::v0::Tile::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<Tile>(new_args.at(0), new_args.at(1));
|
||||
}
|
||||
|
||||
bool op::v0::Tile::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs)
|
||||
{
|
||||
const auto& data = inputs[0];
|
||||
const auto& axis = inputs[1];
|
||||
auto& output = outputs[0];
|
||||
auto repeats_val = read_vector<int64_t>(axis);
|
||||
auto repeats_rank = repeats_val.size();
|
||||
Shape data_shape = data->get_shape();
|
||||
auto data_rank = data_shape.size();
|
||||
auto output_rank = std::max(data_rank, repeats_rank);
|
||||
|
||||
// expand data shape and repeats to output rank
|
||||
data_shape.insert(data_shape.begin(), output_rank - data_rank, 1);
|
||||
repeats_val.insert(repeats_val.begin(), output_rank - repeats_rank, 1);
|
||||
|
||||
Shape output_shape(output_rank);
|
||||
for (size_t i = 0; i < output_rank; i++)
|
||||
{
|
||||
output_shape[i] = data_shape[i] * repeats_val[i];
|
||||
}
|
||||
runtime::reference::tile(data->get_data_ptr<const char>(),
|
||||
output->get_data_ptr<char>(),
|
||||
data->get_shape(),
|
||||
output_shape,
|
||||
data->get_element_type().size());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ngraph/op/op.hpp"
|
||||
#include "ngraph/runtime/host_tensor.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
@@ -43,8 +44,10 @@ namespace ngraph
|
||||
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
bool evaluate(const HostTensorVector& outputs,
|
||||
const HostTensorVector& inputs) override;
|
||||
};
|
||||
}
|
||||
using v0::Tile;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,6 @@ public:
|
||||
construct_constant_slice();
|
||||
construct_constant_select();
|
||||
construct_constant_one_hot();
|
||||
construct_constant_tile();
|
||||
construct_constant_default();
|
||||
}
|
||||
|
||||
@@ -71,7 +70,6 @@ private:
|
||||
void construct_constant_split();
|
||||
void construct_constant_variadic_split();
|
||||
void construct_constant_one_hot();
|
||||
void construct_constant_tile();
|
||||
void construct_constant_default();
|
||||
|
||||
ngraph::BuildNodeExecutorMap m_cfmap;
|
||||
|
||||
@@ -1,104 +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 "constant_folding.hpp"
|
||||
#include "ngraph/op/tile.hpp"
|
||||
#include "ngraph/runtime/reference/tile.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
template <typename T>
|
||||
static shared_ptr<op::Constant> fold_constant_tile(const shared_ptr<op::Constant>& data,
|
||||
const shared_ptr<Node>& tile)
|
||||
{
|
||||
runtime::AlignedBuffer buffer(shape_size(tile->get_shape()) * sizeof(T));
|
||||
T* data_ptr = buffer.get_ptr<T>();
|
||||
// No need to call the reference kernel.
|
||||
if (shape_size(tile->get_shape()) == 0)
|
||||
{
|
||||
return make_shared<op::Constant>(
|
||||
tile->get_output_element_type(0), tile->get_output_shape(0), data_ptr);
|
||||
}
|
||||
|
||||
if (auto tile_v0 = as_type_ptr<op::v0::Tile>(tile))
|
||||
{
|
||||
runtime::reference::tile<T>(
|
||||
data->get_data_ptr<T>(), data_ptr, data->get_shape(), tile_v0->get_shape());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ngraph_error("Unsupported op in tile constant folding.");
|
||||
}
|
||||
|
||||
return make_shared<op::Constant>(
|
||||
tile->get_output_element_type(0), tile->get_output_shape(0), data_ptr);
|
||||
}
|
||||
|
||||
void pass::ConstantFolding::construct_constant_tile()
|
||||
{
|
||||
auto data_label = make_shared<pattern::op::Label>(
|
||||
element::f32, Shape{2, 2, 3}, pattern::has_class<op::Constant>());
|
||||
auto repeats_label =
|
||||
make_shared<pattern::op::Label>(element::i64, Shape{3}, pattern::has_class<op::Constant>());
|
||||
auto tile_v0 = make_shared<op::v0::Tile>(data_label, repeats_label);
|
||||
|
||||
auto constant_tile_callback = [data_label](pattern::Matcher& m) {
|
||||
NGRAPH_DEBUG << "In callback for constant_tile_callback against node = "
|
||||
<< m.get_match_root()->get_name();
|
||||
|
||||
auto pattern_map = m.get_pattern_map();
|
||||
|
||||
auto data = static_pointer_cast<op::Constant>(pattern_map[data_label]);
|
||||
auto tile = m.get_match_root();
|
||||
|
||||
NGRAPH_CHECK(revalidate_and_ensure_static(tile));
|
||||
|
||||
std::shared_ptr<Node> replacement;
|
||||
auto data_type = data->get_output_element_type(0);
|
||||
switch (data_type)
|
||||
{
|
||||
case element::Type_t::undefined:
|
||||
NGRAPH_CHECK(false, "Encountered 'undefined' element type in constant_tile_callback");
|
||||
break;
|
||||
case element::Type_t::dynamic:
|
||||
NGRAPH_CHECK(false, "Encountered 'dynamic' element type in constant_tile_callback");
|
||||
break;
|
||||
case element::Type_t::u1:
|
||||
NGRAPH_CHECK(false, "Encountered 'u1' element type in constant_tile_callback");
|
||||
break;
|
||||
case element::Type_t::boolean: replacement = fold_constant_tile<char>(data, tile); break;
|
||||
case element::Type_t::bf16: replacement = fold_constant_tile<bfloat16>(data, tile); break;
|
||||
case element::Type_t::f16: replacement = fold_constant_tile<float16>(data, tile); break;
|
||||
case element::Type_t::f32: replacement = fold_constant_tile<float>(data, tile); break;
|
||||
case element::Type_t::f64: replacement = fold_constant_tile<double>(data, tile); break;
|
||||
case element::Type_t::i8: replacement = fold_constant_tile<int8_t>(data, tile); break;
|
||||
case element::Type_t::i16: replacement = fold_constant_tile<int16_t>(data, tile); break;
|
||||
case element::Type_t::i32: replacement = fold_constant_tile<int32_t>(data, tile); break;
|
||||
case element::Type_t::i64: replacement = fold_constant_tile<int64_t>(data, tile); break;
|
||||
case element::Type_t::u8: replacement = fold_constant_tile<uint8_t>(data, tile); break;
|
||||
case element::Type_t::u16: replacement = fold_constant_tile<uint16_t>(data, tile); break;
|
||||
case element::Type_t::u32: replacement = fold_constant_tile<uint32_t>(data, tile); break;
|
||||
case element::Type_t::u64: replacement = fold_constant_tile<uint64_t>(data, tile); break;
|
||||
}
|
||||
|
||||
replace_node(m.get_match_root(), replacement);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto tile_matcher_v0 = make_shared<pattern::Matcher>(tile_v0, "ConstantFolding.ConstantTileV0");
|
||||
this->add_matcher(tile_matcher_v0, constant_tile_callback, PassProperty::CHANGE_DYNAMIC_STATE);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//*****************************************************************************
|
||||
// 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 <stdio.h>
|
||||
|
||||
#include "ngraph/check.hpp"
|
||||
#include "ngraph/runtime/reference/tile.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
void runtime::reference::tile(
|
||||
const char* arg, char* out, const Shape& in_shape, const Shape& out_shape, size_t elem_size)
|
||||
{
|
||||
Shape in_shape_expanded(in_shape);
|
||||
in_shape_expanded.insert(in_shape_expanded.begin(), out_shape.size() - in_shape.size(), 1);
|
||||
CoordinateTransform input_transform(in_shape_expanded);
|
||||
CoordinateTransform output_transform(out_shape);
|
||||
|
||||
for (const Coordinate& output_coord : output_transform)
|
||||
{
|
||||
std::vector<size_t> coord;
|
||||
for (auto i = 0; i < output_coord.size(); i++)
|
||||
{
|
||||
auto val = output_coord[i] % in_shape_expanded[i];
|
||||
coord.push_back(val);
|
||||
}
|
||||
Coordinate input_coord(coord);
|
||||
|
||||
memcpy(out + output_transform.index(output_coord) * elem_size,
|
||||
arg + input_transform.index(input_coord) * elem_size,
|
||||
elem_size);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "ngraph/coordinate_transform.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
@@ -26,28 +27,11 @@ namespace ngraph
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
template <typename T>
|
||||
void tile(const T* arg, T* out, const Shape& in_shape, const Shape& out_shape)
|
||||
{
|
||||
Shape in_shape_expanded(in_shape);
|
||||
in_shape_expanded.insert(
|
||||
in_shape_expanded.begin(), out_shape.size() - in_shape.size(), 1);
|
||||
CoordinateTransform input_transform(in_shape_expanded);
|
||||
CoordinateTransform output_transform(out_shape);
|
||||
|
||||
for (const Coordinate& output_coord : output_transform)
|
||||
{
|
||||
std::vector<size_t> coord;
|
||||
for (auto i = 0; i < output_coord.size(); i++)
|
||||
{
|
||||
auto val = output_coord[i] % in_shape_expanded[i];
|
||||
coord.push_back(val);
|
||||
}
|
||||
Coordinate input_coord(coord);
|
||||
out[output_transform.index(output_coord)] =
|
||||
arg[input_transform.index(input_coord)];
|
||||
}
|
||||
}
|
||||
void tile(const char* arg,
|
||||
char* out,
|
||||
const Shape& in_shape,
|
||||
const Shape& out_shape,
|
||||
size_t elem_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1843,7 +1843,7 @@ shared_ptr<Node> JSONDeserializer::deserialize_node(json node_js)
|
||||
|
||||
case OP_TYPEID::Tile:
|
||||
{
|
||||
node = make_shared<op::Tile>(args[0], args[1]);
|
||||
node = make_shared<op::v0::Tile>(args[0], args[1]);
|
||||
break;
|
||||
}
|
||||
case OP_TYPEID::TopK:
|
||||
|
||||
@@ -44,7 +44,7 @@ NGRAPH_TEST(${BACKEND_NAME}, tile_3d_small_data_rank)
|
||||
auto repeats = make_shared<op::Constant>(element::i64, shape_re, vector<int>{2, 2, 1});
|
||||
Shape shape_r{2, 2, 3};
|
||||
|
||||
auto tile = make_shared<op::Tile>(A, repeats);
|
||||
auto tile = make_shared<op::v0::Tile>(A, repeats);
|
||||
|
||||
auto f = make_shared<Function>(tile, ParameterVector{A});
|
||||
|
||||
@@ -71,7 +71,7 @@ NGRAPH_TEST(${BACKEND_NAME}, tile_3d_few_repeats)
|
||||
auto repeats = make_shared<op::Constant>(element::i64, shape_re, vector<int>{2, 1});
|
||||
Shape shape_r{2, 2, 3};
|
||||
|
||||
auto tile = make_shared<op::Tile>(A, repeats);
|
||||
auto tile = make_shared<op::v0::Tile>(A, repeats);
|
||||
|
||||
auto f = make_shared<Function>(tile, ParameterVector{A});
|
||||
|
||||
|
||||
@@ -2658,7 +2658,7 @@ TEST(constant_folding, constant_tile_1d)
|
||||
pass_manager.register_pass<pass::ConstantFolding>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v0::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_const =
|
||||
@@ -2687,7 +2687,7 @@ TEST(constant_folding, constant_tile_3d_small_data_rank)
|
||||
pass_manager.register_pass<pass::ConstantFolding>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v0::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_const =
|
||||
@@ -2716,7 +2716,7 @@ TEST(constant_folding, constant_tile_3d_few_repeats)
|
||||
pass_manager.register_pass<pass::ConstantFolding>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v0::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_const =
|
||||
@@ -2745,7 +2745,7 @@ TEST(constant_folding, constant_tile_1d_0_repeats)
|
||||
pass_manager.register_pass<pass::ConstantFolding>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v0::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_const =
|
||||
@@ -2774,7 +2774,7 @@ TEST(constant_folding, constant_tile_0_rank_data)
|
||||
pass_manager.register_pass<pass::ConstantFolding>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v0::Tile>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_const =
|
||||
|
||||
@@ -965,7 +965,7 @@ namespace
|
||||
|
||||
void op_is_Tile()
|
||||
{
|
||||
op::Tile node;
|
||||
op::v0::Tile node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
|
||||
@@ -150,7 +150,7 @@ NGRAPH_OP(Sum, ngraph::op)
|
||||
NGRAPH_OP(Tan, ngraph::op)
|
||||
NGRAPH_OP(Tanh, ngraph::op)
|
||||
NGRAPH_OP(TensorIterator, ngraph::op)
|
||||
NGRAPH_OP(Tile, ngraph::op)
|
||||
NGRAPH_OP(Tile, ngraph::op::v0)
|
||||
NGRAPH_OP(TopK, ngraph::op::v0)
|
||||
NGRAPH_OP(Unsqueeze, ngraph::op)
|
||||
NGRAPH_OP(Xor, ngraph::op)
|
||||
@@ -25,7 +25,7 @@ TEST(type_prop, tile)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{6, 8, 10});
|
||||
auto param1 = op::Constant::create(element::i64, Shape{3}, {3, 4, 1});
|
||||
auto top = make_shared<op::Tile>(param0, param1);
|
||||
auto top = make_shared<op::v0::Tile>(param0, param1);
|
||||
ASSERT_EQ(top->get_element_type(), element::f32);
|
||||
ASSERT_EQ(top->get_shape(), (Shape{18, 32, 10}));
|
||||
}
|
||||
@@ -34,7 +34,7 @@ TEST(type_prop, tile_small_data_rank)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{8, 10});
|
||||
auto param1 = op::Constant::create(element::i64, Shape{3}, {3, 4, 1});
|
||||
auto top = make_shared<op::Tile>(param0, param1);
|
||||
auto top = make_shared<op::v0::Tile>(param0, param1);
|
||||
ASSERT_EQ(top->get_element_type(), element::f32);
|
||||
ASSERT_EQ(top->get_shape(), (Shape{3, 32, 10}));
|
||||
}
|
||||
@@ -43,7 +43,7 @@ TEST(type_prop, tile_few_repeats)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{6, 8, 10});
|
||||
auto param1 = op::Constant::create(element::i64, Shape{2}, {4, 1});
|
||||
auto top = make_shared<op::Tile>(param0, param1);
|
||||
auto top = make_shared<op::v0::Tile>(param0, param1);
|
||||
ASSERT_EQ(top->get_element_type(), element::f32);
|
||||
ASSERT_EQ(top->get_shape(), (Shape{6, 32, 10}));
|
||||
}
|
||||
Reference in new issue
Block a user