Commit 1a44d7f8 authored by Adam Procter's avatar Adam Procter Committed by Scott Cyphers

Add support for element-type-polymorphic operators (#157)

* Add support for some polymorphic operators (arithmetic, etc.)

* Extend to all other ops except Tuple, which is tricky (not quite sure where to get the needed type info)

* Some tidying(???) up

* Extend to handle Tuple op

* Slightly more descriptive macro name
parent 7d11d579
......@@ -51,6 +51,11 @@ namespace ngraph
/// With non-linear buffers, this will need to be something other than size_t.
virtual size_t get_index_offset(const std::vector<size_t>& indices) = 0;
const element::Type& get_element_type() const
{
return m_tensor_view.get_tensor_view_type()->get_element_type();
}
const Shape& get_shape() const
{
return m_tensor_view.get_tensor_view_type()->get_shape();
......
This diff is collapsed.
......@@ -50,6 +50,37 @@ TEST(execute, test_abc)
ASSERT_EQ((vector<float>{50, 72, 98, 128}), result->get_vector());
}
TEST(execute, test_abc_int64)
{
auto shape = Shape{2, 2};
auto A = make_shared<op::Parameter>(element::Int64::element_type(), shape);
auto B = make_shared<op::Parameter>(element::Int64::element_type(), shape);
auto C = make_shared<op::Parameter>(element::Int64::element_type(), shape);
auto rt = make_shared<TensorViewType>(element::Int64::element_type(), shape);
auto f = make_shared<Function>((A + B) * C, rt, op::Parameters{A, B, C});
auto external = make_shared<ngraph::runtime::ExternalFunction>(f);
auto cf = external->make_call_frame();
// Create some tensors for input/output
auto a = ngraph::runtime::make_tensor<element::Int64>(shape);
*a = vector<element::Int64::type>{1, 2, 3, 4};
auto b = ngraph::runtime::make_tensor<element::Int64>(shape);
*b = vector<element::Int64::type>{5, 6, 7, 8};
auto c = ngraph::runtime::make_tensor<element::Int64>(shape);
*c = vector<element::Int64::type>{9, 10, 11, 12};
auto result = ngraph::runtime::make_tensor<element::Int64>(shape);
(*cf)({a, b, c}, {result});
ASSERT_EQ((vector<element::Int64::type>{54, 80, 110, 144}), result->get_vector());
(*cf)({b, a, c}, {result});
ASSERT_EQ((vector<element::Int64::type>{54, 80, 110, 144}), result->get_vector());
(*cf)({a, c, b}, {result});
ASSERT_EQ((vector<element::Int64::type>{50, 72, 98, 128}), result->get_vector());
}
// Same as test_abc, but using tuples for input and output
TEST(execute, test_abc_tuple)
{
......@@ -92,6 +123,48 @@ TEST(execute, test_abc_tuple)
ASSERT_EQ((vector<float>{50, 72, 98, 128}), result->get_vector());
}
// Same as test_abc, but using tuples for input and output
TEST(execute, test_abc_tuple_int64)
{
auto shape = Shape{2, 2};
auto tensor_view_type = make_shared<TensorViewType>(element::Int64::element_type(), shape);
auto ABC = make_shared<op::Parameter>(
make_shared<TupleType>(ValueTypes{tensor_view_type, tensor_view_type, tensor_view_type}));
auto A = make_shared<op::GetTupleElement>(ABC, 0);
auto B = make_shared<op::GetTupleElement>(ABC, 1);
auto C = make_shared<op::GetTupleElement>(ABC, 2);
auto f = make_shared<Function>(
make_shared<op::Tuple>(Nodes{(A + B) * C}), tensor_view_type, op::Parameters{ABC});
auto external = make_shared<ngraph::runtime::ExternalFunction>(f);
auto cf = external->make_call_frame();
// Create some tensors for input/output
auto a = ngraph::runtime::make_tensor<element::Int64>(shape);
*a = vector<element::Int64::type>{1, 2, 3, 4};
auto b = ngraph::runtime::make_tensor<element::Int64>(shape);
*b = vector<element::Int64::type>{5, 6, 7, 8};
auto c = ngraph::runtime::make_tensor<element::Int64>(shape);
*c = vector<element::Int64::type>{9, 10, 11, 12};
auto abc = ngraph::runtime::make_tuple({a, b, c});
auto bac = ngraph::runtime::make_tuple({b, a, c});
auto acb = ngraph::runtime::make_tuple({a, c, b});
auto result = ngraph::runtime::make_tensor<element::Int64>(shape);
auto result_tuple = ngraph::runtime::make_tuple({result});
(*cf)({abc}, {result_tuple});
ASSERT_EQ((vector<element::Int64::type>{54, 80, 110, 144}), result->get_vector());
(*cf)({bac}, {result_tuple});
ASSERT_EQ((vector<element::Int64::type>{54, 80, 110, 144}), result->get_vector());
(*cf)({acb}, {result_tuple});
ASSERT_EQ((vector<element::Int64::type>{50, 72, 98, 128}), result->get_vector());
}
// Multiple retrive values
TEST(execute, test_tuple_result)
{
......@@ -206,6 +279,36 @@ TEST(execute, test_concat_matrix_rowwise)
result->get_vector());
}
TEST(execute, test_concat_matrix_int64)
{
auto shape_a = Shape{2, 2};
auto A = make_shared<op::Parameter>(element::Int64::element_type(), shape_a);
auto shape_b = Shape{3, 2};
auto B = make_shared<op::Parameter>(element::Int64::element_type(), shape_b);
auto shape_c = Shape{3, 2};
auto C = make_shared<op::Parameter>(element::Int64::element_type(), shape_c);
auto shape_r = Shape{8, 2};
auto rt = make_shared<TensorViewType>(element::Int64::element_type(), Shape{8, 2});
auto f = make_shared<Function>(
make_shared<op::Concat>(Nodes{A, B, C}, 0), rt, op::Parameters{A, B, C});
auto external = make_shared<ngraph::runtime::ExternalFunction>(f);
auto cf = external->make_call_frame();
// Create some tensors for input/output
auto a = ngraph::runtime::make_tensor<element::Int64>(shape_a);
*a = vector<element::Int64::type>{2, 4, 8, 16};
auto b = ngraph::runtime::make_tensor<element::Int64>(shape_b);
*b = vector<element::Int64::type>{1, 2, 4, 8, 16, 32};
auto c = ngraph::runtime::make_tensor<element::Int64>(shape_c);
*c = vector<element::Int64::type>{2, 3, 5, 7, 11, 13};
auto result = ngraph::runtime::make_tensor<element::Int64>(shape_r);
(*cf)({a, b, c}, {result});
ASSERT_EQ((vector<element::Int64::type>{2, 4, 8, 16, 1, 2, 4, 8, 16, 32, 2, 3, 5, 7, 11, 13}),
result->get_vector());
}
TEST(execute, test_concat_vector)
{
auto shape_a = Shape{4};
......@@ -560,6 +663,30 @@ TEST(execute, test_dot_matrix_vector)
ASSERT_EQ((vector<float>{190, 486, 782, 1078}), result->get_vector());
}
TEST(execute, test_dot_matrix_vector_int64)
{
auto shape_a = Shape{4, 4};
auto shape_b = Shape{4};
auto A = make_shared<op::Parameter>(element::Int64::element_type(), shape_a);
auto B = make_shared<op::Parameter>(element::Int64::element_type(), shape_b);
auto rt = make_shared<TensorViewType>(element::Int64::element_type(), shape_b);
auto f = make_shared<Function>(make_shared<op::Dot>(A, B), rt, op::Parameters{A, B});
auto shape_r = Shape{4};
auto external = make_shared<ngraph::runtime::ExternalFunction>(f);
auto cf = external->make_call_frame();
// Create some tensors for input/output
auto a = ngraph::runtime::make_tensor<element::Int64>(shape_a);
*a = vector<element::Int64::type>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
auto b = ngraph::runtime::make_tensor<element::Int64>(shape_b);
*b = vector<element::Int64::type>{17, 18, 19, 20};
auto result = ngraph::runtime::make_tensor<element::Int64>(shape_r);
(*cf)({a, b}, {result});
ASSERT_EQ((vector<element::Int64::type>{190, 486, 782, 1078}), result->get_vector());
}
TEST(execute, test_greater)
{
auto shape = Shape{2, 2, 2};
......@@ -1001,3 +1128,25 @@ TEST(execute, test_broadcast_vector_rowwise)
(*cf)({a}, {result});
ASSERT_EQ((vector<float>{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}), result->get_vector());
}
TEST(execute, test_broadcast_vector_rowwise_int64)
{
auto shape_a = Shape{4};
auto A = make_shared<op::Parameter>(element::Int64::element_type(), shape_a);
auto shape_r = Shape{3, 4};
auto rt = make_shared<TensorViewType>(element::Int64::element_type(), shape_r);
auto f = make_shared<Function>(
make_shared<op::Broadcast>(A, shape_r, AxisSet{0}), rt, op::Parameters{A});
auto external = make_shared<ngraph::runtime::ExternalFunction>(f);
auto cf = external->make_call_frame();
// Create some tensors for input/output
auto a = ngraph::runtime::make_tensor<element::Int64>(shape_a);
*a = vector<element::Int64::type>{1, 2, 3, 4};
auto result = ngraph::runtime::make_tensor<element::Int64>(shape_r);
(*cf)({a}, {result});
ASSERT_EQ((vector<element::Int64::type>{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}),
result->get_vector());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment