mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 09:25:45 +08:00
Merge pull request #25518 from alexlyulkov:al/fixed-gemm-openvino
Fixed OpenVINO gemm layer #25518 Fixed OpenVINO gemm layer The problem was that our layer didn't properly handle all the possible gemm options in OpenVINO mode Fixes #25472 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
f4e5438401
commit
03507e06b4
@ -289,48 +289,54 @@ public:
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
auto ieInpNode = nodes[0].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
std::shared_ptr<ov::Node> matmul;
|
||||
ov::Output<ov::Node> nodeA = nodes[0].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
ov::Output<ov::Node> nodeB;
|
||||
if (const_B)
|
||||
nodeB = std::make_shared<ov::op::v0::Constant>(ov::element::f32, getShape(blobs[0]), blobs[0].data);
|
||||
else
|
||||
nodeB = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
|
||||
if (nodes.size() == 2)
|
||||
int flatten_axis = nodeA.get_shape().size() - nodeB.get_shape().size();
|
||||
if (flatten_axis > 0) {
|
||||
std::vector<int> shape(1 + flatten_axis, 0);
|
||||
shape[shape.size() - 1] = -1;
|
||||
nodeA = std::make_shared<ov::op::v1::Reshape>(
|
||||
nodeA,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::i32, ov::Shape{shape.size()}, shape.data()),
|
||||
true);
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Node> nodeAB = std::make_shared<ov::op::v0::MatMul>(nodeA, nodeB, trans_a, trans_b);
|
||||
if (alpha != 1.0f)
|
||||
{
|
||||
auto& inp2 = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
matmul = std::make_shared<ov::op::v0::MatMul>(ieInpNode, inp2, trans_a, trans_b);
|
||||
nodeAB = std::make_shared<ov::op::v1::Multiply>(
|
||||
nodeAB,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{1}, &alpha));
|
||||
}
|
||||
|
||||
if (!have_bias)
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(nodeAB));
|
||||
|
||||
ov::Output<ov::Node> nodeC;
|
||||
if (const_C)
|
||||
{
|
||||
auto shape_C = blobs.back().total() == blobs.back().size[0] ? ov::Shape{blobs.back().total()} : getShape(blobs.back());
|
||||
nodeC = std::make_shared<ov::op::v0::Constant>(ov::element::f32, shape_C, blobs.back().data);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<ov::Node> ieWeights = std::make_shared<ov::op::v0::Constant>(ov::element::f32, getShape(blobs[0]), blobs[0].data);
|
||||
|
||||
int flatten_axis = ieInpNode.get_shape().size() - ieWeights->get_shape().size();
|
||||
if (flatten_axis > 0) {
|
||||
std::vector<int> shape(1 + flatten_axis, 0);
|
||||
shape[shape.size() - 1] = -1;
|
||||
ieInpNode = std::make_shared<ov::op::v1::Reshape>(
|
||||
ieInpNode,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::i32, ov::Shape{shape.size()}, shape.data()),
|
||||
true
|
||||
);
|
||||
}
|
||||
matmul = std::make_shared<ov::op::v0::MatMul>(ieInpNode, ieWeights, trans_a, trans_b);
|
||||
}
|
||||
if (alpha != 1.0f) {
|
||||
matmul = std::make_shared<ov::op::v1::Multiply>(matmul,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{1}, &alpha)
|
||||
);
|
||||
nodeC = nodes.back().dynamicCast<InfEngineNgraphNode>()->node;
|
||||
}
|
||||
|
||||
if (have_bias && const_C) {
|
||||
Mat bias = blobs.back();
|
||||
auto shape = bias.total() == bias.size[0] ? ov::Shape{bias.total()} : getShape(bias);
|
||||
std::shared_ptr<ov::Node> bias_node = std::make_shared<ov::op::v0::Constant>(ov::element::f32, shape, bias.data);
|
||||
if (beta != 1.0f) {
|
||||
bias_node = std::make_shared<ov::op::v1::Multiply>(bias_node,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{1}, &beta)
|
||||
);
|
||||
}
|
||||
matmul = std::make_shared<ov::op::v1::Add>(matmul, bias_node, ov::op::AutoBroadcastType::NUMPY);
|
||||
if (beta != 1.0f)
|
||||
{
|
||||
nodeC = std::make_shared<ov::op::v1::Multiply>(
|
||||
nodeC,
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{1}, &beta));
|
||||
}
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(matmul));
|
||||
|
||||
auto nodeGemm = std::make_shared<ov::op::v1::Add>(nodeAB, nodeC, ov::op::AutoBroadcastType::NUMPY);
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(nodeGemm));
|
||||
}
|
||||
#endif // HAVE_DNN_NGRAPH
|
||||
|
||||
|
@ -121,8 +121,6 @@
|
||||
"test_gemm_all_attributes",
|
||||
"test_gemm_alpha",
|
||||
"test_gemm_beta",
|
||||
"test_gemm_default_matrix_bias",
|
||||
"test_gemm_default_no_bias",
|
||||
"test_gemm_default_scalar_bias",
|
||||
"test_gemm_default_single_elem_vector_bias",
|
||||
"test_gemm_default_vector_bias",
|
||||
|
Loading…
Reference in New Issue
Block a user