ShuffleChannels ng op and reference implementation revision (#5764)
* Unblock shuffle channels tests from ie test manifest * Add more backend tests * ShiffleChannel reference impl update * Update attr visitor test * Remove unused get_pre_shuffle_shape helper function * Update class descriprion * Add type prop shape tests * Remove NGRAPH_SUPPRESS_DEPRECATED macro * Add single layer tests * Update layer tests * Remove unused header * Move implementation to cpp file
This commit is contained in:
parent
f8759e1982
commit
8dff04df28
@ -36,4 +36,65 @@ INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels4D, ShuffleChannelsLayerTest,
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
// ND support tests
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels6D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(2, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({24, 6, 12, 18, 30, 36})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels5D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(2, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({6, 12, 18, 30, 36})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels3D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(1, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({18, 30, 36})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels2D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(1, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({18, 30})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels1D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(0, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({30})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
|
@ -35,3 +35,40 @@ const auto testCases = ::testing::Combine(::testing::ValuesIn(shuffleParameters)
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_GPU_ShuffleChannels, ShuffleChannelsLayerTest, testCases, ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
// ND support tests
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels3D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(1, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({18, 30, 36})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels2D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(1, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({18, 30})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannels1D, ShuffleChannelsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(std::tuple<int, int>(0, 3)),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(std::vector<size_t >({30})),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU)),
|
||||
ShuffleChannelsLayerTest::getTestCaseName);
|
||||
|
@ -24,14 +24,12 @@ namespace ngraph
|
||||
ShuffleChannels() = default;
|
||||
/// \brief Constructs a ShuffleChannels node.
|
||||
///
|
||||
/// \param data - Node producing the input tensor
|
||||
/// \param axis - channel dimension index in the data tensor. A negative value means
|
||||
/// that the index should be calculated from the back of the input
|
||||
/// data
|
||||
/// shape.
|
||||
/// \param group - number of group the channel dimension specified by axis should
|
||||
/// be
|
||||
/// split into
|
||||
/// \param data Node producing the input tensor.
|
||||
/// \param axis Channel dimension index in the data tensor.
|
||||
/// A negative value means that the index should be
|
||||
/// calculated from the back of the input data shape.
|
||||
/// \param group Number of group the channel dimension should be split into.
|
||||
///
|
||||
ShuffleChannels(const Output<Node>& data,
|
||||
const int64_t axis = 1,
|
||||
const int64_t group = 1);
|
||||
@ -51,11 +49,6 @@ namespace ngraph
|
||||
bool has_evaluate() const override;
|
||||
|
||||
private:
|
||||
/// \brief Generates a shape required to permute the data
|
||||
///
|
||||
/// \param data_shape - Shape of the original input data tensor
|
||||
/// \return A 4D tensor to be used to reshape the input data before shuffling it
|
||||
Shape get_pre_shuffle_shape(const Shape& data_shape) const;
|
||||
bool evaluate_shuffle_channels(const HostTensorVector& outputs,
|
||||
const HostTensorVector& inputs) const;
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
#include "ngraph/shape.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace runtime
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
void shuffle_channels(const char* arg,
|
||||
char* out,
|
||||
const Shape& data_shape,
|
||||
size_t elem_size,
|
||||
const int64_t axis,
|
||||
const int64_t group);
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph/runtime/reference/shuffle_channels.hpp"
|
||||
#include "ngraph/runtime/opt_kernel/reshape.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace runtime
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
void shuffle_channels(const char* arg,
|
||||
char* out,
|
||||
const Shape& data_shape,
|
||||
size_t elem_size,
|
||||
const int64_t axis,
|
||||
const int64_t group)
|
||||
{
|
||||
// Input ND tensor of data_shape (ds) is always considered as 4D tensor with the
|
||||
// following shape:
|
||||
// dim 0: ds[0] * ds[1] * ... * ds[axis-1] (or 1 if axis == 0)
|
||||
// dim 1: group
|
||||
// dim 2: ds[axis] / group
|
||||
// dim 3: ds[axis+1] * ds[axis+2] * ... * ds[ds.size()-1]
|
||||
// (or 1 if axis points to last dimension)
|
||||
|
||||
// The representation of ND tensor as 4D tensor doesn't affect flat data order
|
||||
Shape reshaped_input_shape(4, 1);
|
||||
const size_t axis_zb =
|
||||
axis >= 0 ? axis : axis + data_shape.size(); // Allow negative indices
|
||||
for (size_t i = 0; i < axis_zb; ++i)
|
||||
{
|
||||
// All dimensions before input channels dim axis
|
||||
reshaped_input_shape[0] *= data_shape[i];
|
||||
}
|
||||
reshaped_input_shape[1] = group;
|
||||
reshaped_input_shape[2] = data_shape[axis_zb] / group;
|
||||
for (size_t i = axis_zb + 1; i < data_shape.size(); ++i)
|
||||
{
|
||||
// All dimensions after input channels dim axis
|
||||
reshaped_input_shape[3] *= data_shape[i];
|
||||
}
|
||||
|
||||
// The two dimensions in the middle are swapped
|
||||
const Shape transposed_shape{reshaped_input_shape[0],
|
||||
reshaped_input_shape[2],
|
||||
reshaped_input_shape[1],
|
||||
reshaped_input_shape[3]};
|
||||
AxisVector axis_vector{0, 2, 1, 3};
|
||||
runtime::opt_kernel::reshape(
|
||||
arg, out, reshaped_input_shape, axis_vector, transposed_shape, elem_size);
|
||||
|
||||
// Reshaped 4D tensor is interpreted as ND output tensor with original shape of data
|
||||
// input
|
||||
}
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
@ -10,14 +10,13 @@
|
||||
#include "ngraph/op/shuffle_channels.hpp"
|
||||
#include "ngraph/runtime/host_tensor.hpp"
|
||||
#include "ngraph/runtime/opt_kernel/reshape.hpp"
|
||||
#include "ngraph/runtime/reference/shuffle_channels.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "ngraph/type/element_type_traits.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(op::v0::ShuffleChannels, "ShuffleChannels", 0);
|
||||
|
||||
op::ShuffleChannels::ShuffleChannels(const Output<Node>& data,
|
||||
@ -87,7 +86,8 @@ void op::ShuffleChannels::validate_and_infer_types()
|
||||
}
|
||||
else
|
||||
{
|
||||
set_output_type(0, data_type, PartialShape::dynamic());
|
||||
const auto shape = get_input_partial_shape(0);
|
||||
set_output_type(0, data_type, shape);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,76 +103,19 @@ shared_ptr<Node> op::ShuffleChannels::clone_with_new_inputs(const OutputVector&
|
||||
return make_shared<ShuffleChannels>(new_args.at(0), m_axis, m_group);
|
||||
}
|
||||
|
||||
Shape op::ShuffleChannels::get_pre_shuffle_shape(const Shape& data_shape) const
|
||||
{
|
||||
const Shape& ds = data_shape;
|
||||
|
||||
// in general the resulting shape should contain the following values:
|
||||
// [0]: ds[0] * ds[1] * ... * ds[m_axis-1] (or 1 if m_axis == 0)
|
||||
// [1]: m_group
|
||||
// [2]: ds[axis] / m_group
|
||||
// [3]: ds[axis+1] * ds[axis+2] * ... * ds[ds.size()-1] (or 1 if m_axis points to the last elem
|
||||
// of ds)
|
||||
Shape res(4, 1);
|
||||
|
||||
size_t axis_zb = get_zero_based_axis();
|
||||
for (size_t i = 0; i < axis_zb; ++i)
|
||||
{
|
||||
res[0] *= ds[i];
|
||||
}
|
||||
|
||||
res[1] = m_group;
|
||||
res[2] = ds[axis_zb] / m_group;
|
||||
|
||||
for (size_t i = axis_zb + 1; i < ds.size(); ++i)
|
||||
{
|
||||
res[3] *= ds[i];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool op::ShuffleChannels::evaluate_shuffle_channels(const HostTensorVector& outputs,
|
||||
const HostTensorVector& inputs) const
|
||||
{
|
||||
const auto arg = inputs[0]->get_data_ptr<const char>();
|
||||
auto out = outputs[0]->get_data_ptr<char>();
|
||||
Shape data_shape = inputs[0]->get_shape();
|
||||
const Shape& ds = data_shape;
|
||||
size_t elem_size = inputs[0]->get_element_type().size();
|
||||
const auto data_shape = inputs[0]->get_shape();
|
||||
const size_t elem_size = inputs[0]->get_element_type().size();
|
||||
|
||||
Shape reshaped_out_shape(4, 1);
|
||||
size_t axis_zb = m_axis >= 0 ? m_axis : m_axis + data_shape.size();
|
||||
for (size_t i = 0; i < axis_zb; ++i)
|
||||
{
|
||||
reshaped_out_shape[0] *= ds[i];
|
||||
}
|
||||
outputs[0]->set_element_type(inputs[0]->get_element_type());
|
||||
outputs[0]->set_shape(data_shape);
|
||||
|
||||
reshaped_out_shape[1] = m_group;
|
||||
reshaped_out_shape[2] = ds[axis_zb] / m_group;
|
||||
runtime::reference::shuffle_channels(arg, out, data_shape, elem_size, m_axis, m_group);
|
||||
|
||||
for (size_t i = axis_zb + 1; i < ds.size(); ++i)
|
||||
{
|
||||
reshaped_out_shape[3] *= ds[i];
|
||||
}
|
||||
|
||||
// first reshape from data_shape to reshaped_out_shape is skipped since it doesn't affect
|
||||
// out
|
||||
// data
|
||||
|
||||
Shape transpose_axes_order = {0, 2, 1, 3};
|
||||
Shape transposed_shape(transpose_axes_order.size());
|
||||
|
||||
for (size_t i = 0; i < transpose_axes_order.size(); ++i)
|
||||
{
|
||||
transposed_shape[i] = data_shape.at(transpose_axes_order.at(i));
|
||||
}
|
||||
auto axis_vector = AxisVector{begin(transpose_axes_order), end(transpose_axes_order)};
|
||||
runtime::opt_kernel::reshape(
|
||||
arg, out, reshaped_out_shape, axis_vector, transposed_shape, elem_size);
|
||||
|
||||
// last reshape from transposed_shape to data_shape is skipped since it doesn't affect out
|
||||
// data
|
||||
return true;
|
||||
}
|
||||
bool op::ShuffleChannels::evaluate(const HostTensorVector& outputs,
|
||||
|
@ -442,6 +442,7 @@ set(MULTI_TEST_SRC
|
||||
backend/select.in.cpp
|
||||
backend/selu.in.cpp
|
||||
backend/shape_of.in.cpp
|
||||
backend/shuffle_channels.in.cpp
|
||||
backend/sigmoid.in.cpp
|
||||
backend/sign.in.cpp
|
||||
backend/sin.in.cpp
|
||||
|
@ -570,66 +570,6 @@ NGRAPH_TEST(${BACKEND_NAME}, DISABLED_grn_2d_with_bias)
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_simple)
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::i32, Shape{1, 15, 2, 2});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 1, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data(60);
|
||||
std::iota(std::begin(input_data), std::end(input_data), 0);
|
||||
test_case.add_input(input_data);
|
||||
|
||||
test_case.add_expected_output<int32_t>(
|
||||
Shape{1, 15, 2, 2},
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_negative_axis)
|
||||
{
|
||||
// in this test the output is the same as in shuffle_channels_simple but
|
||||
// the axis value is negative and the C(channels) value is in a different dimension(0) of the
|
||||
// shape
|
||||
const auto data = make_shared<op::Parameter>(element::i32, Shape{15, 2, 1, 2});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, -4, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data(60);
|
||||
std::iota(std::begin(input_data), std::end(input_data), 0);
|
||||
test_case.add_input(input_data);
|
||||
|
||||
test_case.add_expected_output<int32_t>(
|
||||
Shape{15, 2, 1, 2},
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_float)
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f32, Shape{6, 1, 1, 1});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 0, 2);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
test_case.add_input<float>({0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f});
|
||||
|
||||
test_case.add_expected_output<float>(Shape{6, 1, 1, 1}, {0.0f, 3.0f, 1.0f, 4.0f, 2.0f, 5.0f});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
// TODO: Issue: 37534
|
||||
NGRAPH_TEST(${BACKEND_NAME}, DISABLED_squared_difference)
|
||||
{
|
||||
|
192
ngraph/test/backend/shuffle_channels.in.cpp
Normal file
192
ngraph/test/backend/shuffle_channels.in.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "runtime/backend.hpp"
|
||||
#include "util/all_close.hpp"
|
||||
#include "util/all_close_f.hpp"
|
||||
#include "util/engine/test_engines.hpp"
|
||||
#include "util/test_case.hpp"
|
||||
#include "util/test_control.hpp"
|
||||
#include "util/test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
static string s_manifest = "${MANIFEST}";
|
||||
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
|
||||
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_simple)
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::i32, Shape{1, 15, 2, 2});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 1, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data(60);
|
||||
std::iota(std::begin(input_data), std::end(input_data), 0);
|
||||
test_case.add_input(input_data);
|
||||
|
||||
test_case.add_expected_output<int32_t>(
|
||||
Shape{1, 15, 2, 2},
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_negative_axis)
|
||||
{
|
||||
// In this test the output is the same as in shuffle_channels_simple but
|
||||
// the axis value is negative and the C(channels) value is in a different dimension(0) of the
|
||||
// shape
|
||||
const auto data = make_shared<op::Parameter>(element::i32, Shape{15, 2, 1, 2});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, -4, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data(60);
|
||||
std::iota(std::begin(input_data), std::end(input_data), 0);
|
||||
test_case.add_input(input_data);
|
||||
|
||||
test_case.add_expected_output<int32_t>(
|
||||
Shape{15, 2, 1, 2},
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_float)
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f32, Shape{6, 1, 1, 1});
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 0, 2);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
test_case.add_input<float>({0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f});
|
||||
test_case.add_expected_output<float>(Shape{6, 1, 1, 1}, {0.0f, 3.0f, 1.0f, 4.0f, 2.0f, 5.0f});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_1d)
|
||||
{
|
||||
Shape data_shape{15};
|
||||
const auto data = make_shared<op::Parameter>(element::i32, data_shape);
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 0, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
|
||||
|
||||
test_case.add_input(input_data);
|
||||
test_case.add_expected_output<int32_t>(
|
||||
data_shape,
|
||||
{0, 3, 6, 9, 12,
|
||||
1, 4, 7, 10, 13,
|
||||
2, 5, 8, 11, 14});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_2d)
|
||||
{
|
||||
Shape data_shape{15, 4};
|
||||
const auto data = make_shared<op::Parameter>(element::i32, data_shape);
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 0, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59};
|
||||
|
||||
test_case.add_input(input_data);
|
||||
test_case.add_expected_output<int32_t>(
|
||||
data_shape,
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_3d)
|
||||
{
|
||||
Shape data_shape{15, 2, 2};
|
||||
const auto data = make_shared<op::Parameter>(element::i32, data_shape);
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 0, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
|
||||
std::vector<int32_t> input_data{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59};
|
||||
|
||||
test_case.add_input(input_data);
|
||||
test_case.add_expected_output<int32_t>(
|
||||
data_shape,
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, shuffle_channels_5d)
|
||||
{
|
||||
Shape data_shape{2, 2, 15, 2, 2};
|
||||
const auto data = make_shared<op::Parameter>(element::i32, data_shape);
|
||||
auto tested_op = make_shared<op::ShuffleChannels>(data, 2, 5);
|
||||
auto function = make_shared<Function>(tested_op, ParameterVector{data});
|
||||
auto test_case = test::TestCase<TestEngine>(function);
|
||||
|
||||
std::vector<int32_t> input_data{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59};
|
||||
|
||||
test_case.add_input(input_data);
|
||||
test_case.add_expected_output<int32_t>(
|
||||
data_shape,
|
||||
{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59,
|
||||
|
||||
0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 48, 49, 50, 51,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 52, 53, 54, 55,
|
||||
8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 56, 57, 58, 59});
|
||||
|
||||
test_case.run();
|
||||
}
|
@ -752,11 +752,6 @@ gemm_broadcast_axes_1_input_C
|
||||
scale_shift_no_broadcast
|
||||
scale_shift
|
||||
|
||||
# Cannot cast ngraph node ShuffleChannels to CNNLayer!
|
||||
shuffle_channels_simple
|
||||
shuffle_channels_negative_axis
|
||||
shuffle_channels_float
|
||||
|
||||
# Detected op not belonging to opset1!
|
||||
onnx_model_quant_conv_linear
|
||||
onnx_model_quant_conv_linear_2d
|
||||
|
@ -9,12 +9,116 @@
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(type_prop, shuffle_channels_default_4D)
|
||||
{
|
||||
const auto data_input_shape = Shape{3, 9, 4, 5};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_element_type(), element::f32);
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_basic_4D)
|
||||
{
|
||||
const auto data_input_shape = Shape{3, 9, 4, 5};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 1;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_element_type(), element::f32);
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_dynamic_4D)
|
||||
{
|
||||
const auto data_input_shape = PartialShape{Dimension::dynamic(), Dimension(3, 9), 4, Dimension(4, 15)};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 1;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_element_type(), element::f32);
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_dynamic_fully)
|
||||
{
|
||||
const auto data_input_shape = PartialShape::dynamic();
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 1;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_element_type(), element::f32);
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_ND_bigger)
|
||||
{
|
||||
{
|
||||
// 5D
|
||||
const auto data_input_shape = Shape{2, 3, 9, 4, 5};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 2;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
{
|
||||
// 6D
|
||||
const auto data_input_shape = Shape{6, 2, 3, 9, 4, 5};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 3;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_ND_smaller)
|
||||
{
|
||||
{
|
||||
// 3D
|
||||
const auto data_input_shape = Shape{5, 4, 9};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 2;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
{
|
||||
// 2D
|
||||
const auto data_input_shape = Shape{9, 20};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 0;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
{
|
||||
// 1D
|
||||
const auto data_input_shape = Shape{9};
|
||||
const auto data = make_shared<op::Parameter>(element::f32, data_input_shape);
|
||||
const auto axis = 0;
|
||||
const auto group = 3;
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, axis, group);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_output_partial_shape(0), data_input_shape);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, shuffle_channels_axis_validation)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f64, Shape{1, 2, 3, 4});
|
||||
const auto shuffle_channels = make_shared<op::ShuffleChannels>(data, -5, 5);
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, -5, 5);
|
||||
FAIL() << "ShuffleChannels validation did not work. Op node was created with incorrect "
|
||||
"params.";
|
||||
}
|
||||
@ -30,7 +134,7 @@ TEST(type_prop, shuffle_channels_negative_axis_calculation)
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f64, Shape{1, 2, 3, 4});
|
||||
|
||||
const auto shuffle_channels = make_shared<op::ShuffleChannels>(data, -3, 2);
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, -3, 2);
|
||||
|
||||
EXPECT_EQ(shuffle_channels->get_zero_based_axis(), 1);
|
||||
}
|
||||
@ -40,7 +144,7 @@ TEST(type_prop, shuffle_channels_invalid_input_shape)
|
||||
try
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f64, Shape{});
|
||||
const auto shuffle_channels = make_shared<op::ShuffleChannels>(data, 0, 1);
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, 0, 1);
|
||||
FAIL() << "ShuffleChannels validation did not work. Op node was created with incorrect "
|
||||
"params.";
|
||||
}
|
||||
@ -56,7 +160,7 @@ TEST(type_prop, shuffle_channels_invalid_groups_value)
|
||||
try
|
||||
{
|
||||
const auto data = make_shared<op::Parameter>(element::f64, Shape{1, 2, 3, 15});
|
||||
const auto shuffle_channels = make_shared<op::ShuffleChannels>(data, -1, 2);
|
||||
const auto shuffle_channels = make_shared<op::v0::ShuffleChannels>(data, -1, 2);
|
||||
FAIL() << "ShuffleChannels validation did not work. Op node was created with incorrect "
|
||||
"params.";
|
||||
}
|
||||
|
@ -5,28 +5,28 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
#include "ngraph/opsets/opset1.hpp"
|
||||
#include "ngraph/opsets/opset3.hpp"
|
||||
#include "ngraph/opsets/opset4.hpp"
|
||||
#include "ngraph/opsets/opset5.hpp"
|
||||
|
||||
#include "util/visitor.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
using ngraph::test::NodeBuilder;
|
||||
using ngraph::test::ValueMap;
|
||||
|
||||
TEST(attributes, shuffle_channels_op)
|
||||
{
|
||||
NodeBuilder::get_ops().register_factory<opset1::ShuffleChannels>();
|
||||
using ShuffleChannels = opset1::ShuffleChannels;
|
||||
|
||||
NodeBuilder::get_ops().register_factory<ShuffleChannels>();
|
||||
auto data = make_shared<op::Parameter>(element::i32, Shape{200});
|
||||
auto axis = 0;
|
||||
auto groups = 2;
|
||||
auto shuffle_channels = make_shared<opset1::ShuffleChannels>(data, axis, groups);
|
||||
auto shuffle_channels = make_shared<ShuffleChannels>(data, axis, groups);
|
||||
NodeBuilder builder(shuffle_channels);
|
||||
auto g_shuffle_channels = as_type_ptr<opset1::ShuffleChannels>(builder.create());
|
||||
auto g_shuffle_channels = as_type_ptr<ShuffleChannels>(builder.create());
|
||||
|
||||
const auto expected_attr_count = 2;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
|
||||
EXPECT_EQ(g_shuffle_channels->get_axis(), shuffle_channels->get_axis());
|
||||
EXPECT_EQ(g_shuffle_channels->get_group(), shuffle_channels->get_group());
|
||||
|
Loading…
Reference in New Issue
Block a user