[CPU][ARM] Dynamic shapes support in ARM transformations (#17548)
This commit is contained in:
1 parent
a106eb0d75
commit
1588a33217
19 files changed
+912
-59
No files matched your search
+15
-6
@@ -19,11 +19,20 @@ ov::intel_cpu::ConvertGroupConvolution::ConvertGroupConvolution() {
|
||||
if (!gconv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto data_shape = gconv->get_input_shape(Inputs::Data);
|
||||
const unsigned int channel_axis = 1;
|
||||
const auto& input0 = gconv->input_value(0);
|
||||
const auto& output_shape = gconv->get_output_partial_shape(0);
|
||||
const auto& data_shape = input0.get_partial_shape();
|
||||
// Weights layout GOIYX
|
||||
size_t groups = gconv->get_input_shape(Inputs::Weights)[0];
|
||||
if (groups == data_shape.at(1) && groups == gconv->get_output_shape(0)[1]) { // depthwise case
|
||||
int64_t groups = gconv->get_input_shape(Inputs::Weights)[0];
|
||||
|
||||
if (data_shape[channel_axis].is_dynamic() ||
|
||||
output_shape[channel_axis].is_dynamic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (groups == data_shape[channel_axis].get_length() &&
|
||||
groups == output_shape[channel_axis].get_length()) { // depthwise case
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -33,12 +42,12 @@ ov::intel_cpu::ConvertGroupConvolution::ConvertGroupConvolution() {
|
||||
groups);
|
||||
replace_nodes.push_back(split_weights);
|
||||
|
||||
auto axis = ov::opset8::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {1});
|
||||
auto axis = ov::opset8::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {channel_axis});
|
||||
auto split = std::make_shared<ov::opset1::Split>(gconv->input_value(Inputs::Data), axis, groups);
|
||||
replace_nodes.push_back(split);
|
||||
|
||||
ngraph::NodeVector concat_inputs;
|
||||
for (size_t g = 0; g < groups; g++) {
|
||||
for (int64_t g = 0; g < groups; g++) {
|
||||
auto out = split->output(g);
|
||||
auto filter = std::make_shared<ov::opset1::Squeeze>(split_weights->output(g),
|
||||
ov::opset8::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {0}));
|
||||
|
||||
@@ -6,6 +6,56 @@
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* ConvertGroupConvolution detects GroupConvolution and replaces it
|
||||
* with a set of Convolution operations. Number of Convolution operations
|
||||
* equals to number of groups.
|
||||
*
|
||||
* Before:
|
||||
*
|
||||
* +--------------+ +---------------+
|
||||
* | Input tensor | | Kernel tensor |
|
||||
* +-----------+--+ +-+-------------+
|
||||
* | |
|
||||
* +----v---------v----+
|
||||
* | Group Convolution |
|
||||
* +---------+---------+
|
||||
* |
|
||||
* +------v------+
|
||||
* | Result |
|
||||
* +-------------+
|
||||
*
|
||||
* After:
|
||||
*
|
||||
* +--------------+ +--------------+ +---------------+ +--------------+
|
||||
* | Input tensor | | Constant (1) | | Kernel tensor | | Constant (0) |
|
||||
* +-----------+--+ +-+------------+ +-----------+---+ +-+------------+
|
||||
* | | | |
|
||||
* +-v---------v-+ +-v---------v-+
|
||||
* | Split | | Split |
|
||||
* +-+-----------+--------+ +-+---------+-+
|
||||
* | | | |
|
||||
* | | +-----------v--+ +-v------------+
|
||||
* | | | Squeeze | | Squeeze |
|
||||
* | +----------+---+--------------+ +-+------------+
|
||||
* | | | |
|
||||
* | | +---------------+ |
|
||||
* | | | |
|
||||
* +-----------v---------v------------+ +-----------v---------v------------+
|
||||
* | Convolution | | Convolution |
|
||||
* +-----------------------------+----+ +---+------------------------------+
|
||||
* | |
|
||||
* +-----v----------v------+
|
||||
* | Concat |
|
||||
* +----------+------------+
|
||||
* |
|
||||
* +----------v------------+
|
||||
* | Result |
|
||||
* +-----------------------+
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
|
||||
|
||||
+19
-14
@@ -19,7 +19,8 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertConv1DBase::convert_conv1d_t
|
||||
return false;
|
||||
}
|
||||
|
||||
auto input_shape = conv->get_input_shape(0);
|
||||
const auto& input0 = conv->input_value(0);
|
||||
const auto& input_shape = input0.get_partial_shape();
|
||||
// is Conv1D
|
||||
if (input_shape.size() != 3) {
|
||||
return false;
|
||||
@@ -27,16 +28,19 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertConv1DBase::convert_conv1d_t
|
||||
|
||||
auto input = conv->input_value(0);
|
||||
auto weights = conv->input_value(1);
|
||||
auto input2d_shape = input_shape;
|
||||
input2d_shape.push_back(1);
|
||||
auto in2d_shape = std::make_shared<ov::opset8::Constant>(ngraph::element::i64, ngraph::Shape{4}, input2d_shape);
|
||||
|
||||
auto weights2d_shape = weights.get_shape();
|
||||
weights2d_shape.push_back(1);
|
||||
auto w_shape = std::make_shared<ov::opset8::Constant>(ngraph::element::i64, ngraph::Shape{weights2d_shape.size()}, weights2d_shape);
|
||||
|
||||
auto input2d = std::make_shared<ov::opset8::Reshape>(input, in2d_shape, true);
|
||||
auto weights2d = std::make_shared<ov::opset8::Reshape>(weights, w_shape, true);
|
||||
auto getUnsqueeze = [&](const ngraph::Output<ngraph::Node>& node) {
|
||||
auto rank = node.get_partial_shape().rank().get_length();
|
||||
return std::make_shared<ov::opset8::Unsqueeze>(node,
|
||||
ov::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {rank}));
|
||||
};
|
||||
|
||||
auto input2d = getUnsqueeze(input);
|
||||
auto weights2d = getUnsqueeze(weights);
|
||||
|
||||
auto conv2d = std::make_shared<Conv>(input2d,
|
||||
weights2d,
|
||||
@@ -46,8 +50,9 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertConv1DBase::convert_conv1d_t
|
||||
ngraph::Strides{conv->get_dilations()[0], 1},
|
||||
conv->get_auto_pad());
|
||||
|
||||
auto in_shape = std::make_shared<ov::opset8::Constant>(ngraph::element::i64, ngraph::Shape{3}, conv->get_output_shape(0));
|
||||
auto reshape = std::make_shared<ov::opset8::Reshape>(conv2d, in_shape, true);
|
||||
auto reshape = std::make_shared<ov::opset8::Squeeze>(
|
||||
conv2d,
|
||||
ov::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {input_shape.rank().get_length()}));
|
||||
|
||||
reshape->set_friendly_name(conv->get_friendly_name());
|
||||
ngraph::copy_runtime_info(conv, {input2d, weights2d, conv2d, reshape});
|
||||
@@ -58,16 +63,16 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertConv1DBase::convert_conv1d_t
|
||||
|
||||
ov::intel_cpu::ConvertConv1D::ConvertConv1D() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::Convolution>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::any_input(ngraph::pattern::has_static_shape())},
|
||||
ngraph::pattern::has_static_shape()), "ConvertConvolutionToArm");
|
||||
ngraph::pattern::wrap_type<ov::opset8::Convolution>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::any_input()}),
|
||||
"ConvertConvolutionToArm");
|
||||
register_matcher(m, convert_conv1d_to_conv2d<ov::opset8::Convolution>());
|
||||
}
|
||||
|
||||
ov::intel_cpu::ConvertGroupConv1D::ConvertGroupConv1D() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::GroupConvolution>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::any_input(ngraph::pattern::has_static_shape())},
|
||||
ngraph::pattern::has_static_shape()), "ConvertGroupConvolutionToArm");
|
||||
ngraph::pattern::wrap_type<ov::opset8::GroupConvolution>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::any_input()}),
|
||||
"ConvertGroupConvolutionToArm");
|
||||
register_matcher(m, convert_conv1d_to_conv2d<ov::opset8::GroupConvolution>());
|
||||
}
|
||||
@@ -5,6 +5,51 @@
|
||||
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* ConvertConv1DBase detects 1D Convolution / GroupConvolution and replaces
|
||||
* it with the sequence Unsqueeze - 2D Convolution / GroupConvolution - Squeeze.
|
||||
* Unsqueeze adds the additional dimension to Convolution inputs and Squeeze
|
||||
* removes the additional dimention from the Convolution output.
|
||||
*
|
||||
* Before:
|
||||
*
|
||||
* +--------------+ +---------------+
|
||||
* | Input tensor | | Kernel tensor |
|
||||
* +-----------+--+ +-+-------------+
|
||||
* | |
|
||||
* +-v---------v-+
|
||||
* | Convolution |
|
||||
* +------+------+
|
||||
* |
|
||||
* +------v------+
|
||||
* | Result |
|
||||
* +-------------+
|
||||
*
|
||||
* After:
|
||||
*
|
||||
* +--------------+ +--------------+ +---------------+ +--------------+
|
||||
* | Input tensor | | Constant (1) | | Kernel tensor | | Constant (1) |
|
||||
* +-----------+--+ +-+------------+ +-----------+---+ +-+------------+
|
||||
* | | | |
|
||||
* +-v---------v-+ +-v---------v-+
|
||||
* | Unsqueeze | | Unsqueeze |
|
||||
* +------+------+ +------+------+
|
||||
* | |
|
||||
* +------v------------------------------------v------+ +--------------+
|
||||
* | Convolution | | Constant (1) |
|
||||
* +---------------------------------------------+----+ +-+------------+
|
||||
* | |
|
||||
* +-v---------v-+
|
||||
* | Squeeze |
|
||||
* +------+------+
|
||||
* |
|
||||
* +------v------+
|
||||
* | Result |
|
||||
* +-------------+
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
class ConvertConv1DBase: public ngraph::pass::MatcherPass {
|
||||
|
||||
+21
-15
@@ -16,16 +16,26 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertReduceMultiAxisBase::convert
|
||||
if (!std::dynamic_pointer_cast<T>(reduce)) {
|
||||
return false;
|
||||
}
|
||||
if (ngraph::shape_size(reduce->input_value(1).get_shape()) <= 1) {
|
||||
|
||||
const auto& input0 = reduce->input_value(0);
|
||||
const auto& input1 = reduce->input_value(1);
|
||||
const auto& data_shape0 = input0.get_partial_shape();
|
||||
const auto& data_shape1 = input1.get_partial_shape();
|
||||
if (data_shape0.is_dynamic() ||
|
||||
data_shape1.is_dynamic()) {
|
||||
return false;
|
||||
}
|
||||
auto reduction_axes = std::dynamic_pointer_cast<ov::opset8::Constant>(reduce->input_value(1).get_node_shared_ptr());
|
||||
|
||||
if (ngraph::shape_size(input1.get_shape()) <= 1) {
|
||||
return false;
|
||||
}
|
||||
auto reduction_axes = std::dynamic_pointer_cast<ov::opset8::Constant>(input1.get_node_shared_ptr());
|
||||
if (!reduction_axes) {
|
||||
return false;
|
||||
}
|
||||
auto axes = reduction_axes->cast_vector<int64_t>();
|
||||
ngraph::NodeVector new_ops;
|
||||
std::shared_ptr<ngraph::Node> node = reduce->input_value(0).get_node_shared_ptr();
|
||||
std::shared_ptr<ngraph::Node> node = input0.get_node_shared_ptr();
|
||||
for (auto axis : axes) {
|
||||
auto reduction_axis = ov::opset8::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {axis});
|
||||
node = std::make_shared<T>(node, reduction_axis, true);
|
||||
@@ -46,32 +56,28 @@ ngraph::matcher_pass_callback ov::intel_cpu::ConvertReduceMultiAxisBase::convert
|
||||
|
||||
ov::intel_cpu::ConvertReduceProd::ConvertReduceProd() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceProd>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()},
|
||||
ngraph::pattern::has_static_shape()), "ConvertReduceProd");
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceProd>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()}), "ConvertReduceProd");
|
||||
register_matcher(m, convert_reduce<ov::opset8::ReduceProd>());
|
||||
}
|
||||
|
||||
ov::intel_cpu::ConvertReduceMin::ConvertReduceMin() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceMin>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()},
|
||||
ngraph::pattern::has_static_shape()), "ConvertReduceMin");
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceMin>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()}), "ConvertReduceMin");
|
||||
register_matcher(m, convert_reduce<ov::opset8::ReduceMin>());
|
||||
}
|
||||
|
||||
ov::intel_cpu::ConvertReduceMax::ConvertReduceMax() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceMax>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()},
|
||||
ngraph::pattern::has_static_shape()), "ConvertReduceMax");
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceMax>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()}), "ConvertReduceMax");
|
||||
register_matcher(m, convert_reduce<ov::opset8::ReduceMax>());
|
||||
}
|
||||
|
||||
ov::intel_cpu::ConvertReduceSum::ConvertReduceSum() {
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceSum>({ngraph::pattern::any_input(ngraph::pattern::has_static_shape()),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()},
|
||||
ngraph::pattern::has_static_shape()), "ConvertReduceSum");
|
||||
ngraph::pattern::wrap_type<ov::opset8::ReduceSum>({ngraph::pattern::any_input(),
|
||||
ngraph::pattern::wrap_type<ov::opset8::Constant>()}), "ConvertReduceSum");
|
||||
register_matcher(m, convert_reduce<ov::opset8::ReduceSum>());
|
||||
}
|
||||
+44
@@ -6,6 +6,50 @@
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* ConvertReduceMultiAxisBase detects Reduce operations that do not support
|
||||
* multi-axis input by ACL: Min, Max, Sum, Prod. Multi-axis Reduce operation
|
||||
* is replaced with a sequence of single-axe Reduce operations.
|
||||
*
|
||||
* Before:
|
||||
*
|
||||
* +--------------+ +-------------------+
|
||||
* | Data | | Axes tensor [A,B] |
|
||||
* +-----------+--+ +-+-----------------+
|
||||
* | |
|
||||
* +----v---------v----+
|
||||
* | Reduce |
|
||||
* +---------+---------+
|
||||
* |
|
||||
* +------v------+
|
||||
* | Result |
|
||||
* +-------------+
|
||||
*
|
||||
* After:
|
||||
*
|
||||
* +-------------+ +---------------+
|
||||
* | Data | | Axes scalar A |
|
||||
* +---------+---+ +----+----------+
|
||||
* | |
|
||||
* +-v------------v--+ +-----------------+
|
||||
* | Reduce | | Axes scalar B |
|
||||
* +--------------+--+ +---+-------------+
|
||||
* | |
|
||||
* +-v-----------v---+
|
||||
* | Reduce |
|
||||
* +-------+---------+
|
||||
* |
|
||||
* +-------v---------+
|
||||
* | Reshape |
|
||||
* +-------+---------+
|
||||
* |
|
||||
* +-------v---------+
|
||||
* | Result |
|
||||
* +-----------------+
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ endif()
|
||||
if(X86_64)
|
||||
list(APPEND EXCLUDED_SOURCE_PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests/instances/arm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/arm)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/src/arm)
|
||||
else()
|
||||
list(APPEND EXCLUDED_SOURCE_PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests/instances/x64
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/x64)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/src/x64)
|
||||
# temporary disable all custom tests for ARM
|
||||
list(APPEND EXCLUDED_SOURCE_PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests
|
||||
@@ -35,6 +35,7 @@ else()
|
||||
file(GLOB_RECURSE TMP_LIST_OF_TEST_CLASSES ${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests/classes/*.cpp)
|
||||
file(GLOB_RECURSE TMP_LIST_OF_COMMON_TEST_INSTANCES ${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests/instances/common/*.cpp)
|
||||
file(GLOB_RECURSE TMP_LIST_OF_ARM_TEST_INSTANCES ${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests/instances/arm/*.cpp)
|
||||
file(GLOB_RECURSE TMP_LIST_OF_ARM_TEST_INSTANCES ${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/arm/*.cpp)
|
||||
list(APPEND TMP_LIST_OF_EXPLICITLY_ENABLED_TESTS
|
||||
${TMP_LIST_OF_TEST_CLASSES} ${TMP_LIST_OF_COMMON_TEST_INSTANCES} ${TMP_LIST_OF_ARM_TEST_INSTANCES})
|
||||
set(TMP_EXPLICITLY_ENABLED_TESTS "${TMP_LIST_OF_EXPLICITLY_ENABLED_TESTS}")
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <debug.h>
|
||||
#include <shared_test_classes/base/ov_subgraph.hpp>
|
||||
#include <ngraph_functions/builders.hpp>
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include <common_test_utils/ov_tensor_utils.hpp>
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp"
|
||||
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "test_utils/convolution_params.hpp"
|
||||
|
||||
using namespace CPUTestUtils;
|
||||
using namespace ov::test;
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::helpers;
|
||||
|
||||
namespace CPUSubgraphTestsDefinitions {
|
||||
|
||||
typedef std::tuple<InputShape> groupConvLayerCPUTestParamsSet;
|
||||
|
||||
class GroupConvToConvTransformationCPUTest: public testing::WithParamInterface<groupConvLayerCPUTestParamsSet>,
|
||||
virtual public SubgraphBaseTest, public CPUTestsBase {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<groupConvLayerCPUTestParamsSet> obj) {
|
||||
InputShape inputShapes;
|
||||
std::tie(inputShapes) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=" << inputShapes;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
static const size_t numOfGroups = 2;
|
||||
void SetUp() override {
|
||||
targetDevice = CommonTestUtils::DEVICE_CPU;
|
||||
InputShape inputShapes;
|
||||
std::tie(inputShapes) = this->GetParam();
|
||||
|
||||
init_input_shapes({inputShapes});
|
||||
|
||||
std::shared_ptr<Node> conv;
|
||||
const std::vector<size_t> kernelSize = {1};
|
||||
const std::vector<size_t> strides = {1};
|
||||
const std::vector<ptrdiff_t> padBegin = {0};
|
||||
const std::vector<ptrdiff_t> padEnd = {0};
|
||||
const std::vector<size_t> dilation = {1};
|
||||
const size_t numOutChannels = 30;
|
||||
const op::PadType paddingType = op::PadType::EXPLICIT;
|
||||
|
||||
auto inputParams = ngraph::builder::makeDynamicParams(ngraph::element::f32, inputDynamicShapes);
|
||||
auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(inputParams));
|
||||
conv = builder::makeGroupConvolution(paramOuts.front(), element::f32, kernelSize, strides, padBegin, padEnd, dilation,
|
||||
paddingType, numOutChannels, numOfGroups);
|
||||
|
||||
ResultVector results;
|
||||
results.push_back(std::make_shared<opset5::Result>(conv));
|
||||
|
||||
function = std::make_shared<ngraph::Function>(results, inputParams, "groupConvolution");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(GroupConvToConvTransformationCPUTest, CompareWithRefs) {
|
||||
run();
|
||||
CheckNumberOfNodesWithType(compiledModel, "Split", 1);
|
||||
CheckNumberOfNodesWithType(compiledModel, "Convolution", numOfGroups);
|
||||
CheckNumberOfNodesWithType(compiledModel, "Concatenation", 1);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::vector<InputShape> inShapes = {
|
||||
{{}, {{ 2, 12, 7 }}},
|
||||
{
|
||||
//dynamic shape
|
||||
{-1, 12, {1, 20}},
|
||||
{ //target static shapes
|
||||
{ 2, 12, 7 },
|
||||
{ 1, 12, 5 }
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto groupConvTransformationParams = ::testing::Combine(::testing::ValuesIn(inShapes));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GroupConvToConvTransformationTest, GroupConvToConvTransformationCPUTest,
|
||||
groupConvTransformationParams, GroupConvToConvTransformationCPUTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace CPUSubgraphTestsDefinitions
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <debug.h>
|
||||
#include <shared_test_classes/base/ov_subgraph.hpp>
|
||||
#include <ngraph_functions/builders.hpp>
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include <common_test_utils/ov_tensor_utils.hpp>
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp"
|
||||
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "test_utils/convolution_params.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace CPUTestUtils;
|
||||
using namespace ov::test;
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::helpers;
|
||||
|
||||
namespace CPUSubgraphTestsDefinitions {
|
||||
|
||||
typedef std::tuple<nodeType,
|
||||
InputShape> conv1dConvertCPUTestParamsSet;
|
||||
|
||||
class Conv1dConvertTransformationCPUTest: public testing::WithParamInterface<conv1dConvertCPUTestParamsSet>,
|
||||
virtual public SubgraphBaseTest, public CPUTestsBase {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<conv1dConvertCPUTestParamsSet> obj) {
|
||||
InputShape inputShapes;
|
||||
nodeType convType;
|
||||
std::tie(convType, inputShapes) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << nodeType2str(convType) << "_";
|
||||
result << "IS=" << inputShapes;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
targetDevice = CommonTestUtils::DEVICE_CPU;
|
||||
InputShape inputShapes;
|
||||
nodeType convType;
|
||||
std::tie(convType, inputShapes) = this->GetParam();
|
||||
|
||||
init_input_shapes({inputShapes});
|
||||
|
||||
std::shared_ptr<Node> conv;
|
||||
const std::vector<size_t> kernelSize = {1};
|
||||
const std::vector<size_t> strides = {1};
|
||||
const std::vector<ptrdiff_t> padBegin = {0};
|
||||
const std::vector<ptrdiff_t> padEnd = {0};
|
||||
const std::vector<size_t> dilation = {1};
|
||||
const size_t numOutChannels = 30;
|
||||
const size_t numOfGroups = 2;
|
||||
const op::PadType paddingType = op::PadType::EXPLICIT;
|
||||
|
||||
auto inputParams = ngraph::builder::makeDynamicParams(ngraph::element::f32, inputDynamicShapes);
|
||||
auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(inputParams));
|
||||
switch (convType) {
|
||||
case nodeType::convolution : {
|
||||
conv = builder::makeConvolution(paramOuts.front(), element::f32, kernelSize, strides, padBegin, padEnd, dilation,
|
||||
paddingType, numOutChannels);
|
||||
break;
|
||||
}
|
||||
case nodeType::groupConvolution : {
|
||||
conv = builder::makeGroupConvolution(paramOuts.front(), element::f32, kernelSize, strides, padBegin, padEnd, dilation,
|
||||
paddingType, numOutChannels, numOfGroups);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw std::runtime_error("Conv1dConvertTransformationCPUTest doesn't support this type of operation");
|
||||
}
|
||||
}
|
||||
|
||||
ResultVector results;
|
||||
results.push_back(std::make_shared<opset5::Result>(conv));
|
||||
|
||||
function = std::make_shared<ngraph::Function>(results, inputParams, "convolution");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Conv1dConvertTransformationCPUTest, CompareWithRefs) {
|
||||
run();
|
||||
CheckNumberOfNodesWithType(compiledModel, "Reshape", 2);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const std::vector<nodeType> convType = { nodeType::convolution, nodeType::groupConvolution };
|
||||
std::vector<InputShape> inputShapes1d = {
|
||||
{{}, {{ 2, 64, 7 }}},
|
||||
{{}, {{ 1, 32, 7 }}},
|
||||
{
|
||||
//dynamic shape
|
||||
{ -1, 64, {1, 20} },
|
||||
{ //target static shapes
|
||||
{ 2, 64, 7 },
|
||||
{ 1, 64, 9 }
|
||||
}
|
||||
},
|
||||
{
|
||||
//dynamic shape
|
||||
{ -1, 32, {1, 20} },
|
||||
{ //target static shapes
|
||||
{ 2, 32, 7 },
|
||||
{ 1, 32, 9 }
|
||||
}
|
||||
},
|
||||
{
|
||||
//dynamic shape
|
||||
{ {1, 20}, 64, -1 },
|
||||
{ //target static shapes
|
||||
{ 2, 64, 7 },
|
||||
{ 1, 64, 5 }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const auto groupConvTransformationParams = ::testing::Combine(::testing::ValuesIn(convType),
|
||||
::testing::ValuesIn(inputShapes1d));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GroupConvToConvTransformationTest, Conv1dConvertTransformationCPUTest,
|
||||
groupConvTransformationParams, Conv1dConvertTransformationCPUTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace CPUSubgraphTestsDefinitions
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <debug.h>
|
||||
#include <shared_test_classes/base/ov_subgraph.hpp>
|
||||
#include <ngraph_functions/builders.hpp>
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include <common_test_utils/ov_tensor_utils.hpp>
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp"
|
||||
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "test_utils/convolution_params.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace CPUTestUtils;
|
||||
using namespace ov::test;
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::helpers;
|
||||
|
||||
namespace CPUSubgraphTestsDefinitions {
|
||||
|
||||
typedef std::tuple<
|
||||
std::vector<int>, // Axis to reduce order
|
||||
ngraph::helpers::ReductionType, // Reduce operation type
|
||||
std::vector<InputShape> // Input shapes
|
||||
> reduceConvertCPUTestParamsSet;
|
||||
|
||||
class reduceTransformationCPUTest: public testing::WithParamInterface<reduceConvertCPUTestParamsSet>,
|
||||
virtual public SubgraphBaseTest, public CPUTestsBase {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<reduceConvertCPUTestParamsSet> obj) {
|
||||
std::vector<InputShape> inputShapes;
|
||||
std::vector<int> axes;
|
||||
ReductionType reductionType;
|
||||
std::tie(axes, reductionType, inputShapes) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "type=" << reductionType << "_";
|
||||
result << "IS=(";
|
||||
for (const auto& shape : inputShapes) {
|
||||
result << CommonTestUtils::partialShape2str({shape.first}) << "_";
|
||||
}
|
||||
result << ")_axes=" << CommonTestUtils::vec2str(axes) << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
int numberOfExpectedReduce;
|
||||
void SetUp() override {
|
||||
targetDevice = CommonTestUtils::DEVICE_CPU;
|
||||
std::vector<int> axes;
|
||||
bool keepDims = true;
|
||||
std::vector<InputShape> inputShapes;
|
||||
std::tie(axes, reductionType, inputShapes) = this->GetParam();
|
||||
numberOfExpectedReduce = axes.size();
|
||||
|
||||
init_input_shapes(inputShapes);
|
||||
|
||||
auto params = ngraph::builder::makeDynamicParams(ngraph::element::f32, inputDynamicShapes);
|
||||
auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
|
||||
std::vector<size_t> shapeAxes;
|
||||
shapeAxes.push_back(axes.size());
|
||||
auto reductionAxesNode = std::dynamic_pointer_cast<ngraph::Node>(
|
||||
std::make_shared<ngraph::opset3::Constant>(ngraph::element::Type_t::i64, ngraph::Shape(shapeAxes), axes));
|
||||
|
||||
const auto reduce = ngraph::builder::makeReduce(paramOuts[0], reductionAxesNode, keepDims, reductionType);
|
||||
function = makeNgraphFunction(ElementType::f32, params, reduce, "Reduce");
|
||||
}
|
||||
private:
|
||||
ngraph::helpers::ReductionType reductionType;
|
||||
};
|
||||
|
||||
TEST_P(reduceTransformationCPUTest, CompareWithRefs) {
|
||||
run();
|
||||
CheckNumberOfNodesWithType(compiledModel, "Reduce", numberOfExpectedReduce);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::vector<std::vector<ov::test::InputShape>> inputShapes = {
|
||||
{{{}, {{2, 19, 2, 9}}}}
|
||||
};
|
||||
const std::vector<ReductionType> reductionTypes = {
|
||||
ReductionType::Min,
|
||||
ReductionType::Max,
|
||||
ReductionType::Sum,
|
||||
ReductionType::Prod
|
||||
};
|
||||
const std::vector<std::vector<int>> axes = {
|
||||
{0, 1},
|
||||
{0, 2},
|
||||
{0, 3},
|
||||
{1, 2},
|
||||
{1, 3},
|
||||
{2, 3},
|
||||
{0, 1, 3},
|
||||
{0, 2, 3},
|
||||
{1, 2, 3},
|
||||
{0, 1, 2, 3}
|
||||
};
|
||||
|
||||
const auto reduceTransformationParams = ::testing::Combine(::testing::ValuesIn(axes),
|
||||
::testing::ValuesIn(reductionTypes),
|
||||
::testing::ValuesIn(inputShapes));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GroupConvToConvTransformationTest, reduceTransformationCPUTest,
|
||||
reduceTransformationParams, reduceTransformationCPUTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace CPUSubgraphTestsDefinitions
|
||||
@@ -88,7 +88,7 @@ function(create_target_per_test_for_directory TEST_DIR TARGET_PREFIX)
|
||||
endfunction()
|
||||
|
||||
if(ENABLE_CPU_SPECIFIC_TARGET_PER_TEST)
|
||||
create_target_per_test_for_directory(${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/src ov_cpu_func_subgraph)
|
||||
create_target_per_test_for_directory(${CMAKE_CURRENT_SOURCE_DIR}/subgraph_tests/src/arm ov_cpu_func_subgraph)
|
||||
create_target_per_test_for_directory(${CMAKE_CURRENT_SOURCE_DIR}/single_layer_tests ov_cpu_func_slt)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -12,14 +12,16 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
ie_add_compiler_flags(/wd5051)
|
||||
endif()
|
||||
|
||||
if (NOT OPENVINO_ARCH_X86_64)
|
||||
set(EXCLUDED_SOURCE_PATHS_FOR_NON_X64 ${CMAKE_CURRENT_SOURCE_DIR}/jit_kernel_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/registers_pool.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ngraph_transformations/convert_to_interaction.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ngraph_transformations/snipptes_mark_skipped.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ngraph_transformations/mul_add_to_fma.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/snippets_transformations
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nodes/eltwise_node_test.cpp)
|
||||
if (X86_64)
|
||||
set(EXCLUDED_SOURCE_PATHS_FOR_UNIT_TEST
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ngraph_transformations/arm)
|
||||
else()
|
||||
set(EXCLUDED_SOURCE_PATHS_FOR_UNIT_TEST
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/jit_kernel_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/registers_pool.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ngraph_transformations/x64
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/snippets_transformations
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nodes/eltwise_node_test.cpp)
|
||||
endif()
|
||||
|
||||
addIeTargetTest(
|
||||
@@ -35,7 +37,7 @@ addIeTargetTest(
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:inference_engine_snippets,SOURCE_DIR>/include
|
||||
EXCLUDED_SOURCE_PATHS
|
||||
${EXCLUDED_SOURCE_PATHS_FOR_NON_X64}
|
||||
${EXCLUDED_SOURCE_PATHS_FOR_UNIT_TEST}
|
||||
OBJECT_FILES
|
||||
${OBJ_LIB}
|
||||
LINK_LIBRARIES
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset7.hpp>
|
||||
#include <transformations/cpu_opset/arm/pass/convert_group_conv.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <ov_ops/type_relaxed.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ov::intel_cpu;
|
||||
|
||||
template <class T>
|
||||
static std::shared_ptr<ov::Model> createInitGraph(std::shared_ptr<ngraph::opset1::Parameter> param, ngraph::Shape weights_shape) {
|
||||
auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, weights_shape, { 1 });
|
||||
auto conv = std::make_shared<T>(param,
|
||||
weights,
|
||||
ngraph::Strides{1},
|
||||
ngraph::CoordinateDiff{0},
|
||||
ngraph::CoordinateDiff{0},
|
||||
ngraph::Strides{1});
|
||||
|
||||
return std::make_shared<ngraph::Function>(ngraph::NodeVector{ conv }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertGroupConvIsApplied) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 6, 224});
|
||||
function = createInitGraph<ngraph::opset1::GroupConvolution>(param, ngraph::Shape{2, 1, 3, 5});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertGroupConvolution>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
const unsigned int groups = 2;
|
||||
const unsigned int channel_axis = 1;
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 6, 224});
|
||||
auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{groups, 1, 3, 5}, { 1 });
|
||||
auto split_weights = std::make_shared<ngraph::opset1::Split>(weights,
|
||||
ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{}, {0}),
|
||||
groups);
|
||||
auto axis = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{}, {channel_axis});
|
||||
auto split = std::make_shared<ngraph::opset1::Split>(param, axis, groups);
|
||||
ngraph::NodeVector concat_inputs;
|
||||
for (size_t g = 0; g < groups; g++) {
|
||||
auto out = split->output(g);
|
||||
auto filter = std::make_shared<ngraph::opset1::Squeeze>(split_weights->output(g),
|
||||
ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{}, {0}));
|
||||
auto conv = std::make_shared<ngraph::opset1::Convolution>(out,
|
||||
filter,
|
||||
ngraph::Strides{1},
|
||||
ngraph::CoordinateDiff{0},
|
||||
ngraph::CoordinateDiff{0},
|
||||
ngraph::Strides{1});
|
||||
concat_inputs.push_back(conv);
|
||||
}
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(concat_inputs, 1);
|
||||
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ concat }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertGroupConvIsNotAppliedForDepthwiseCase) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 224});
|
||||
function = createInitGraph<ngraph::opset1::GroupConvolution>(param, ngraph::Shape{2, 1, 1, 5});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertGroupConvolution>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 224});
|
||||
function_ref = createInitGraph<ngraph::opset1::GroupConvolution>(param, ngraph::Shape{2, 1, 1, 5});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertGroupConvIsNotAppliedForDynamicShapes) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape{1, -1, 224});
|
||||
function = createInitGraph<ngraph::opset1::GroupConvolution>(param, ngraph::Shape{2, 1, 1, 5});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertGroupConvolution>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape{1, -1, 224});
|
||||
function_ref = createInitGraph<ngraph::opset1::GroupConvolution>(param, ngraph::Shape{2, 1, 1, 5});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset7.hpp>
|
||||
#include <transformations/cpu_opset/arm/pass/convert_group_conv1d.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <ov_ops/type_relaxed.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ov::intel_cpu;
|
||||
|
||||
template <class T>
|
||||
static std::shared_ptr<ov::Model> createInitGraph(ngraph::Shape param_shape, ngraph::Shape weights_shape) {
|
||||
auto type = ngraph::element::f32;
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(type, param_shape);
|
||||
auto weights = ngraph::opset1::Constant::create(type, weights_shape, { 1 });
|
||||
bool is1Dinput = param_shape.size() == 3;
|
||||
auto conv = std::make_shared<T>(param,
|
||||
weights,
|
||||
is1Dinput ? ngraph::Strides{1} : ngraph::Strides{1, 1},
|
||||
is1Dinput ? ngraph::CoordinateDiff{0} : ngraph::CoordinateDiff{0, 0},
|
||||
is1Dinput ? ngraph::CoordinateDiff{0} : ngraph::CoordinateDiff{0, 0},
|
||||
is1Dinput ? ngraph::Strides{1} : ngraph::Strides{1, 1});
|
||||
|
||||
return std::make_shared<ngraph::Function>(ngraph::NodeVector{ conv }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::shared_ptr<ov::Model> createTransformedGraph(ngraph::Shape param_shape, ngraph::Shape weights_shape) {
|
||||
auto getUnsqueeze = [&](const ngraph::Output<ngraph::Node>& node) {
|
||||
auto rank = node.get_partial_shape().rank().get_length();
|
||||
return std::make_shared<ov::opset8::Unsqueeze>(node,
|
||||
ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {rank}));
|
||||
};
|
||||
auto type = ngraph::element::f32;
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(type, param_shape);
|
||||
auto weights = ngraph::opset1::Constant::create(type, weights_shape, { 1 });
|
||||
auto input2d = getUnsqueeze(param);
|
||||
auto weights2d = getUnsqueeze(weights);
|
||||
auto conv2d = std::make_shared<T>(input2d,
|
||||
weights2d,
|
||||
ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 0},
|
||||
ngraph::CoordinateDiff{0, 0},
|
||||
ngraph::Strides{1, 1});
|
||||
|
||||
auto reshape = std::make_shared<ngraph::opset1::Squeeze>(conv2d,
|
||||
ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {3}));
|
||||
return std::make_shared<ngraph::Function>(ngraph::NodeVector{ reshape }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertConv1DIsAppliedFor1DShapes) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
function = createInitGraph<ngraph::opset1::Convolution>(ngraph::Shape{2, 64, 7}, ngraph::Shape{ 30, 64, 1 });
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertConv1D>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
function_ref = createTransformedGraph<ngraph::opset1::Convolution>(ngraph::Shape{2, 64, 7}, ngraph::Shape{30, 64, 1});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertConv1DIsNotAppliedFor2DShapes) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
function = createInitGraph<ngraph::opset1::Convolution>(ngraph::Shape{2, 64, 7, 1}, ngraph::Shape{30, 64, 1, 1});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertConv1D>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
function_ref = createInitGraph<ngraph::opset1::Convolution>(ngraph::Shape{2, 64, 7, 1}, ngraph::Shape{30, 64, 1, 1});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertGroupConv1DIsAppliedFor1dShapes) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
function = createInitGraph<ngraph::opset1::GroupConvolution>(ngraph::Shape{1, 12, 64}, ngraph::Shape{4, 1, 3, 5});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertGroupConv1D>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
function_ref = createTransformedGraph<ngraph::opset1::GroupConvolution>(ngraph::Shape{1, 12, 64}, ngraph::Shape{4, 1, 3, 5});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, CheckConvertGroupConv1DIsNotAppliedFor2DShapes) {
|
||||
std::shared_ptr<ov::Model> function(nullptr), function_ref(nullptr);
|
||||
{
|
||||
function = createInitGraph<ngraph::opset1::GroupConvolution>(ngraph::Shape{1, 12, 64, 1}, ngraph::Shape{4, 1, 3, 5, 1});
|
||||
ov::pass::Manager manager;
|
||||
manager.register_pass<ConvertGroupConv1D>();
|
||||
manager.run_passes(function);
|
||||
}
|
||||
{
|
||||
function_ref = createInitGraph<ngraph::opset1::GroupConvolution>(ngraph::Shape{1, 12, 64, 1}, ngraph::Shape{4, 1, 3, 5, 1});
|
||||
}
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset7.hpp>
|
||||
#include <transformations/cpu_opset/arm/pass/convert_reduce_multi_axis.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <ov_ops/type_relaxed.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ov::intel_cpu;
|
||||
|
||||
template <class T>
|
||||
class ConvertReduceMultiAxisTest : public testing::Test {};
|
||||
|
||||
template <class T>
|
||||
static std::shared_ptr<ov::Model> createInitGraph(std::shared_ptr<ngraph::opset1::Parameter> param) {
|
||||
auto axes = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {0, 1});
|
||||
auto reduce = std::make_shared<T>(param, axes, true);
|
||||
return std::make_shared<ngraph::Function>(ngraph::NodeVector{ reduce }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::shared_ptr<ov::Model> createRefGraph(ov::Shape param_shape) {
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, param_shape);
|
||||
std::vector<int64_t> axes = {0, 1};
|
||||
ngraph::NodeVector new_ops;
|
||||
std::shared_ptr<ngraph::Node> node = param;
|
||||
for (auto axis : axes) {
|
||||
auto reduction_axis = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{}, {axis});
|
||||
node = std::make_shared<T>(node, reduction_axis, true);
|
||||
new_ops.push_back(node);
|
||||
}
|
||||
auto reshape_shape = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{param_shape.size()}, {1, 1, 2, 9});
|
||||
auto reshape = std::make_shared<ngraph::opset1::Reshape>(node, reshape_shape, true);
|
||||
|
||||
return std::make_shared<ngraph::Function>(ngraph::NodeVector{ reshape }, ngraph::ParameterVector{ param });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static bool registerAndRunReducePass(std::shared_ptr<ov::Model> function) {
|
||||
ov::pass::Manager manager;
|
||||
if (std::is_same<T, ngraph::opset1::ReduceMin>::value) {
|
||||
manager.register_pass<ConvertReduceMin>();
|
||||
} else if (std::is_same<T, ngraph::opset1::ReduceMax>::value) {
|
||||
manager.register_pass<ConvertReduceMax>();
|
||||
} else if (std::is_same<T, ngraph::opset1::ReduceSum>::value) {
|
||||
manager.register_pass<ConvertReduceSum>();
|
||||
} else if (std::is_same<T, ngraph::opset1::ReduceProd>::value) {
|
||||
manager.register_pass<ConvertReduceProd>();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
manager.run_passes(function);
|
||||
return true;
|
||||
}
|
||||
|
||||
static ngraph::Shape static_param_shape = ngraph::Shape{2, 19, 2, 9};
|
||||
static ngraph::PartialShape dynamic_param_shape = ngraph::PartialShape{2, -1, 2, 9};
|
||||
|
||||
TYPED_TEST_SUITE_P(ConvertReduceMultiAxisTest);
|
||||
|
||||
TYPED_TEST_P(ConvertReduceMultiAxisTest, CheckConvertReduceTransformationIsApplied) {
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, static_param_shape);
|
||||
auto function = createInitGraph<TypeParam>(param);
|
||||
auto function_ref = createRefGraph<TypeParam>(static_param_shape);
|
||||
|
||||
if (!registerAndRunReducePass<TypeParam>(function)) {
|
||||
FAIL() << "Reduce pass is not registered.";
|
||||
}
|
||||
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TYPED_TEST_P(ConvertReduceMultiAxisTest, CheckConvertReduceTransformationIsNotAppliedForDynaimcShapes) {
|
||||
auto param = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, dynamic_param_shape);
|
||||
auto function = createInitGraph<TypeParam>(param);
|
||||
auto function_ref = createInitGraph<TypeParam>(param);
|
||||
|
||||
if (!registerAndRunReducePass<TypeParam>(function)) {
|
||||
FAIL() << "Reduce pass is not registered.";
|
||||
}
|
||||
|
||||
auto res = compare_functions(function, function_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(ConvertReduceMultiAxisTest,
|
||||
CheckConvertReduceTransformationIsApplied,
|
||||
CheckConvertReduceTransformationIsNotAppliedForDynaimcShapes);
|
||||
|
||||
using reduceTypes = ::testing::Types<ngraph::opset1::ReduceMin,
|
||||
ngraph::opset1::ReduceMax,
|
||||
ngraph::opset1::ReduceSum,
|
||||
ngraph::opset1::ReduceProd>;
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(ConvertReduce, ConvertReduceMultiAxisTest, reduceTypes);
|
||||
File renamed without changes.
+4
-3
@@ -7,6 +7,7 @@
|
||||
#include <snippets_helpers.hpp>
|
||||
#include <transformations/snippets/x64/pass/snippets_mark_skipped.hpp>
|
||||
#include "snippets/pass/tokenization.hpp"
|
||||
#include "snippets/pass/collapse_subgraph.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
@@ -17,11 +18,11 @@ public:
|
||||
void run() {
|
||||
ASSERT_TRUE(function);
|
||||
manager.register_pass<ov::intel_cpu::SnippetsMarkSkipped>();
|
||||
manager.register_pass<ngraph::snippets::pass::EnumerateNodes>();
|
||||
manager.register_pass<ngraph::snippets::pass::TokenizeSnippets>();
|
||||
manager.register_pass<ov::snippets::pass::EnumerateNodes>();
|
||||
manager.register_pass<ov::snippets::pass::TokenizeSnippets>();
|
||||
//
|
||||
// todo: This is a temporary work-around. remove when MatMul tokenization is supported through general pipeline
|
||||
manager.get_pass_config()->set_callback<ngraph::snippets::pass::TokenizeSnippets>(
|
||||
manager.get_pass_config()->set_callback<ov::snippets::pass::TokenizeSnippets>(
|
||||
[](const std::shared_ptr<const ov::Node>& n) -> bool {
|
||||
return ov::is_type<const ov::op::v0::MatMul>(n);
|
||||
});
|
||||
+6
-5
@@ -7,6 +7,7 @@
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
#include "snippets/pass/fq_decomposition.hpp"
|
||||
#include "snippets/pass/tokenization.hpp"
|
||||
#include "snippets/pass/collapse_subgraph.hpp"
|
||||
#include "fake_quantize_function.hpp"
|
||||
#include "snippets/op/subgraph.hpp"
|
||||
#include "transformations/snippets/x64/pass/snippets_mark_skipped.hpp"
|
||||
@@ -20,9 +21,9 @@ class FakeQuantizeTokenizationTest : public TransformationTestsF {
|
||||
public:
|
||||
void register_passes() {
|
||||
manager.register_pass<ov::intel_cpu::SnippetsMarkSkipped>();
|
||||
manager.register_pass<ngraph::snippets::pass::EnumerateNodes>();
|
||||
manager.register_pass<ngraph::snippets::pass::TokenizeSnippets>();
|
||||
manager.get_pass_config()->set_callback<ngraph::snippets::pass::TokenizeSnippets>([](const std::shared_ptr<const ov::Node>& n) -> bool {
|
||||
manager.register_pass<ov::snippets::pass::EnumerateNodes>();
|
||||
manager.register_pass<ov::snippets::pass::TokenizeSnippets>();
|
||||
manager.get_pass_config()->set_callback<ov::snippets::pass::TokenizeSnippets>([](const std::shared_ptr<const ov::Node>& n) -> bool {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
@@ -31,10 +32,10 @@ public:
|
||||
TransformationTestsF::TearDown();
|
||||
|
||||
auto subgraph = FunctionHelper::getSubgraph(function);
|
||||
auto body = subgraph == nullptr ? nullptr : std::dynamic_pointer_cast<ngraph::snippets::op::Subgraph>(subgraph)->body_ptr();
|
||||
auto body = subgraph == nullptr ? nullptr : std::dynamic_pointer_cast<ov::snippets::op::Subgraph>(subgraph)->body_ptr();
|
||||
|
||||
auto subgraph_ref = FunctionHelper::getSubgraph(function_ref);
|
||||
auto body_ref = subgraph_ref == nullptr ? nullptr : std::dynamic_pointer_cast<ngraph::snippets::op::Subgraph>(subgraph_ref)->body_ptr();
|
||||
auto body_ref = subgraph_ref == nullptr ? nullptr : std::dynamic_pointer_cast<ov::snippets::op::Subgraph>(subgraph_ref)->body_ptr();
|
||||
|
||||
if ((body != nullptr) && (body_ref != nullptr)) {
|
||||
auto res = comparator.compare(body, body_ref);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <subgraph_simple.hpp>
|
||||
#include <transformations/snippets/x64/pass/mul_add_to_fma.hpp>
|
||||
#include <transformations/snippets/x64/op/fused_mul_add.hpp>
|
||||
|
||||
#include "snippets/op/scalar.hpp"
|
||||
#include "lowering_utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
@@ -60,7 +60,7 @@ protected:
|
||||
ParameterVector parameters{data0, data1};
|
||||
std::shared_ptr<Node> data2;
|
||||
if (scalar_input) {
|
||||
data2 = std::make_shared<ngraph::snippets::op::Scalar>(precision, Shape{}, 2.f);
|
||||
data2 = std::make_shared<ov::snippets::op::Scalar>(precision, Shape{}, 2.f);
|
||||
} else {
|
||||
auto parameter = std::make_shared<op::v0::Parameter>(precision, input_shapes[2]);
|
||||
parameters.push_back(parameter);
|
||||
@@ -132,12 +132,12 @@ protected:
|
||||
}
|
||||
|
||||
std::shared_ptr<SnippetsFunctionBase> snippets_function;
|
||||
std::shared_ptr<ngraph::snippets::Generator> generator;
|
||||
std::shared_ptr<ov::snippets::Generator> generator;
|
||||
ov::pass::Manager cpu_manager;
|
||||
};
|
||||
|
||||
TEST_P(MulAddToFMATests, MulAddToFMATests) {
|
||||
auto subgraph = getLoweredSubgraph(snippets_function->getOriginal(), master_shape, {}, {}, cpu_manager, generator);
|
||||
auto subgraph = getLoweredSubgraph(snippets_function->getOriginal(), master_shape, {}, {}, cpu_manager, {}, generator);
|
||||
model = subgraph->body_ptr();
|
||||
model_ref = snippets_function->getLowered();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user