//***************************************************************************** // Copyright 2017-2019 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 <algorithm> #include <cinttypes> #include <cmath> #include <cstdlib> #include <random> #include <string> #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" #include "util/all_close.hpp" #include "util/all_close_f.hpp" #include "util/ndarray.hpp" #include "util/random.hpp" #include "util/test_control.hpp" #include "util/test_tools.hpp" using namespace std; using namespace ngraph; static string s_manifest = "${MANIFEST}"; // Trivial case. NGRAPH_TEST(${BACKEND_NAME}, argmin_trivial) { Shape shape{4, 3}; Shape rshape{3}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMin>(A, 0, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, vector<float>{12, 2, 10, 9, 8, 4, 6, 1, 5, 3, 11, 7}); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((vector<int>{3, 2, 1}), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmin_4D_axis_3_i64) { Shape shape{2, 2, 5, 5}; // NCHW ->(0,1,2,3) Shape rshape{2, 2, 5}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMin>(A, 3, element::i64), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 4>({{{{0.5f, 1.5f, 0.8f, 2.9f, 1.05f}, // img 0 ch 0 {0.5f, 3.5f, 2.0f, 1.0f, 0.2f}, {2.0f, 0.0f, 2.2f, 0.2f, 1.4f}, {2.9f, 0.0f, 1.52f, 1.2f, 2.22f}, {5.0f, 2.0f, 1.0f, 0.5f, 0.85f}}, {{0.25f, 0.02f, 0.02f, 2.2f, 0.001f}, // img 0 ch 1 {1.0f, 0.2f, 3.0f, 0.25f, 1.14f}, {2.25f, 10.1f, 1.0f, 0.02f, 2.22f}, {3.2f, 1.002f, 0.001f, 0.2f, 6.0f}, {2.0f, 0.0f, 0.0f, 0.0f, 0.0f}}}, {{{0.0f, 2.2f, 1.2f, 1.6f, 0.2f}, // img 1 ch 0 {0.01f, 0.0f, 0.22f, 0.02f, 1.1f}, {0.01f, 0.5f, 1.6f, 0.2f, 3.2f}, {2.4f, 0.5f, 0.0f, 3.0f, 0.1f}, {0.0f, 0.5f, 0.4f, 0.8f, 1.0f}}, {{2.0f, 1.0f, 0.0f, 0.0f, 1.0f}, // img 1 ch 1 {0.0f, 2.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 2.0f, 0.0f, 2.0f}, {1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 0.0f, 2.0f}}}}) .get_vector()); auto result = backend->create_tensor(element::i64, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int64_t, 3>({{{0, 4, 1, 1, 3}, // ch0 {4, 1, 3, 2, 1}}, // {{0, 1, 0, 2, 0}, // ch1 {2, 0, 3, 3, 1}}}) // .get_vector()), read_vector<int64_t>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmin_4D_axis_3) { Shape shape{2, 2, 5, 5}; // NCHW ->(0,1,2,3) Shape rshape{2, 2, 5}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMin>(A, 3, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 4>({{{{0.5f, 1.5f, 0.8f, 2.9f, 1.05f}, // img 0 ch 0 {0.5f, 3.5f, 2.0f, 1.0f, 0.2f}, {2.0f, 0.0f, 2.2f, 0.2f, 1.4f}, {2.9f, 0.0f, 1.52f, 1.2f, 2.22f}, {5.0f, 2.0f, 1.0f, 0.5f, 0.85f}}, {{0.25f, 0.02f, 0.02f, 2.2f, 0.001f}, // img 0 ch 1 {1.0f, 0.2f, 3.0f, 0.25f, 1.14f}, {2.25f, 10.1f, 1.0f, 0.02f, 2.22f}, {3.2f, 1.002f, 0.001f, 0.2f, 6.0f}, {2.0f, 0.0f, 0.0f, 0.0f, 0.0f}}}, {{{0.0f, 2.2f, 1.2f, 1.6f, 0.2f}, // img 1 ch 0 {0.01f, 0.0f, 0.22f, 0.02f, 1.1f}, {0.01f, 0.5f, 1.6f, 0.2f, 3.2f}, {2.4f, 0.5f, 0.0f, 3.0f, 0.1f}, {0.0f, 0.5f, 0.4f, 0.8f, 1.0f}}, {{2.0f, 1.0f, 0.0f, 0.0f, 1.0f}, // img 1 ch 1 {0.0f, 2.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 2.0f, 0.0f, 2.0f}, {1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 0.0f, 2.0f}}}}) .get_vector()); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int, 3>({{{0, 4, 1, 1, 3}, // ch0 {4, 1, 3, 2, 1}}, // {{0, 1, 0, 2, 0}, // ch1 {2, 0, 3, 3, 1}}}) // .get_vector()), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_trivial) { Shape shape{4, 3}; // HW -> (0,1) Shape rshape{3}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 0, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, vector<float>{9, 2, 10, 12, 8, 4, 6, 1, 5, 3, 11, 7}); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((vector<int>{1, 3, 0}), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_3D_axis_0) // Along Channels { Shape shape{3, 4, 2}; // CHW ->(0,1,2) Shape rshape{4, 2}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 0, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 3>({{{8, 4}, //ch0 {12, 10}, {2, 9}, {1, 5}}, {{6, 7}, //ch1 {11, 3}, {9, 2}, {10, 12}}, {{8, 4}, //ch2 {6, 1}, {5, 3}, {11, 7}}}) .get_vector()); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int, 2>({{0, 1}, //r0 {0, 0}, //r1 {1, 0}, //r2 {2, 1}}) //r3 .get_vector()), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_3D_axis_1) // Along Height { Shape shape{3, 4, 2}; // CHW ->(0,1,2) Shape rshape{3, 2}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 1, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 3>({{{8, 4}, //ch0 {12, 10}, {2, 9}, {1, 5}}, {{6, 7}, //ch1 {11, 3}, {9, 2}, {10, 12}}, {{8, 4}, //ch2 {6, 1}, {5, 3}, {11, 7}}}) .get_vector()); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int, 2>({{1, 1}, // {1, 3}, // {3, 3}}) .get_vector()), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_3D_axis_2) // Along Width { Shape shape{3, 4, 2}; // CHW ->(0,1,2) Shape rshape{3, 4}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 2, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 3>({{{8, 4}, //ch0 {12, 10}, {2, 9}, {1, 5}}, {{6, 7}, //ch1 {11, 3}, {9, 2}, {10, 12}}, {{8, 4}, //ch2 {6, 1}, {5, 3}, {11, 7}}}) .get_vector()); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int, 2>({{0, 0, 1, 1}, // {1, 0, 0, 1}, // {0, 0, 0, 0}}) // .get_vector()), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_4D_axis_3) { Shape shape{2, 2, 5, 5}; // NCHW ->(0,1,2,3) Shape rshape{2, 2, 5}; auto A = make_shared<op::Parameter>(element::f32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 3, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f32, shape); copy_data(a, test::NDArray<float, 4>({{{{0, 1, 0, 2, 1}, // img 0 ch 0 {0, 3, 2, 0, 0}, {2, 0, 0, 0, 1}, {2, 0, 1, 1, 2}, {0, 2, 1, 0, 0}}, {{0, 0, 0, 2, 0}, // img 0 ch 1 {0, 2, 3, 0, 1}, {2, 0, 1, 0, 2}, {3, 1, 0, 0, 0}, {2, 0, 0, 0, 0}}}, {{{0, 2, 1, 1, 0}, // img 1 ch 0 {0, 0, 2, 0, 1}, {0, 0, 1, 2, 3}, {2, 0, 0, 3, 0}, {0, 0, 0, 0, 0}}, {{2, 1, 0, 0, 1}, // img 1 ch 1 {0, 2, 0, 0, 0}, {1, 1, 2, 0, 2}, {1, 1, 1, 0, 1}, {1, 0, 0, 0, 2}}}}) .get_vector()); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int, 3>({{{3, 1, 0, 0, 1}, {3, 2, 0, 0, 0}}, //ch0 {{1, 2, 4, 3, 0}, {0, 1, 2, 0, 4}}}) //ch1 .get_vector()), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmin_trivial_in_i32) { Shape shape{4, 3}; Shape rshape{3}; auto A = make_shared<op::Parameter>(element::i32, shape); auto f = make_shared<Function>(make_shared<op::ArgMin>(A, 0, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::i32, shape); copy_data(a, vector<int32_t>{12, 2, 10, 9, 8, 4, 6, 1, 5, 3, 11, 7}); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((vector<int>{3, 2, 1}), read_vector<int>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmax_4D_axis_3_i64_in_i32) { Shape shape{2, 2, 5, 5}; // NCHW ->(0,1,2,3) Shape rshape{2, 2, 5}; auto A = make_shared<op::Parameter>(element::i32, shape); auto f = make_shared<Function>(make_shared<op::ArgMax>(A, 3, element::i64), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::i32, shape); copy_data(a, test::NDArray<int32_t, 4>({{{{0, 1, 0, 2, 1}, // img 0 ch 0 {0, 3, 2, 0, 0}, {2, 0, 0, 0, 1}, {2, 0, 1, 1, 2}, {0, 2, 1, 0, 0}}, {{0, 0, 0, 2, 0}, // img 0 ch 1 {0, 2, 3, 0, 1}, {2, 0, 1, 0, 2}, {3, 1, 0, 0, 0}, {2, 0, 0, 0, 0}}}, {{{0, 2, 1, 1, 0}, // img 1 ch 0 {0, 0, 2, 0, 1}, {0, 0, 1, 2, 3}, {2, 0, 0, 3, 0}, {0, 0, 0, 0, 0}}, {{2, 1, 0, 0, 1}, // img 1 ch 1 {0, 2, 0, 0, 0}, {1, 1, 2, 0, 2}, {1, 1, 1, 0, 1}, {1, 0, 0, 0, 2}}}}) .get_vector()); auto result = backend->create_tensor(element::i64, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((test::NDArray<int64_t, 3>({{{3, 1, 0, 0, 1}, {3, 2, 0, 0, 0}}, //ch0 {{1, 2, 4, 3, 0}, {0, 1, 2, 0, 4}}}) //ch1 .get_vector()), read_vector<int64_t>(result)); } NGRAPH_TEST(${BACKEND_NAME}, argmin_trivial_in_double) { Shape shape{4, 3}; Shape rshape{3}; auto A = make_shared<op::Parameter>(element::f64, shape); auto f = make_shared<Function>(make_shared<op::ArgMin>(A, 0, element::i32), ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); // Create some tensors for input/output auto a = backend->create_tensor(element::f64, shape); copy_data(a, vector<double>{12, 2, 10, 9, 8, 4, 6, 1, 5, 3, 11, 7}); auto result = backend->create_tensor(element::i32, rshape); auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); EXPECT_EQ((vector<int32_t>{3, 2, 1}), read_vector<int32_t>(result)); }