[CPU] Reuse the new nGraph shape infer functionality to the MKLDNN plugin (#9220)
This commit is contained in:
parent
822cb48a1e
commit
89f4a569d5
@ -47,12 +47,12 @@ template<class T>
|
||||
void shape_infer(const ov::op::util::ArithmeticReductionKeepDims* op, const std::vector<T> &input_shapes, std::vector<T> &output_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}) {
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 2 && output_shapes.size() == 1);
|
||||
reduce_shape_infer(op, op->get_keep_dims(), input_shapes[0], output_shapes[0]);
|
||||
reduce_shape_infer(op, op->get_keep_dims(), input_shapes[0], output_shapes[0], constant_data);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void shape_infer(const ov::op::util::LogicalReductionKeepDims* op, const std::vector<T> &input_shapes, std::vector<T> &output_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}) {
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 2 && output_shapes.size() == 1);
|
||||
reduce_shape_infer(op, op->get_keep_dims(), input_shapes[0], output_shapes[0]);
|
||||
reduce_shape_infer(op, op->get_keep_dims(), input_shapes[0], output_shapes[0], constant_data);
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ void copy_shape_infer(const OpType* op, const std::vector<T>& input_shapes, std:
|
||||
|
||||
template <class OpType, class T>
|
||||
void first_input_passthrough_infer(const OpType* op, const std::vector<T>& input_shapes, std::vector<T>& output_shapes) {
|
||||
NODE_VALIDATION_CHECK(op, output_shapes.size() == 1, "Incorrect number of output shapes");
|
||||
NODE_VALIDATION_CHECK(op, output_shapes.size() == 1 && input_shapes.size() >= 1,
|
||||
"Incorrect number of input and output shapes");
|
||||
output_shapes[0] = input_shapes[0];
|
||||
}
|
||||
|
||||
|
@ -111,8 +111,9 @@ MKLDNNNode::MKLDNNNode(const std::shared_ptr<ngraph::Node>& op, const mkldnn::en
|
||||
isDynamic = std::any_of(inputShapes.begin(), inputShapes.end(), [](const Shape& shape){ return shape.isDynamic(); }) ||
|
||||
std::any_of(outputShapes.begin(), outputShapes.end(), [](const Shape& shape){ return shape.isDynamic(); });
|
||||
|
||||
if (isDynamic)
|
||||
createShapeInferSubgraph(op);
|
||||
if (isDynamic) {
|
||||
shapeInference = make_shape_inference(op);
|
||||
}
|
||||
|
||||
const auto& rtInfo = op->get_rt_info();
|
||||
if (rtInfo.count("originalLayersNames")) {
|
||||
@ -1419,54 +1420,71 @@ bool MKLDNNNode::needShapeInfer() const {
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNNode::shapeInfer() const {
|
||||
std::vector<Shape> shapes;
|
||||
for (size_t i = 0; i < opToShapeInfer->get_input_size(); i++) {
|
||||
shapes.push_back(opToShapeInfer->get_input_partial_shape(i).rank().get_length() == 0 ? Shape{} :
|
||||
getParentEdgesAtPort(i)[0]->getMemory().getDesc().getShape());
|
||||
}
|
||||
|
||||
auto newOutputShapes = shapeInferGeneric(shapes);
|
||||
|
||||
IE_ASSERT(newOutputShapes.size() == outputShapes.size());
|
||||
|
||||
return newOutputShapes;
|
||||
return shapeInferGeneric();
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNNode::shapeInferGeneric(const std::vector<Shape>& shapes) const {
|
||||
if (shapes.size() < opToShapeInfer->get_input_size()) {
|
||||
IE_THROW(Unexpected) << "MKLDNNNode::shapeInferGeneric input shapes vector size is " << shapes.size() << ", but " << opToShapeInfer->get_input_size() <<
|
||||
" required for node with name: " << getName();
|
||||
}
|
||||
std::vector<VectorDims> MKLDNNNode::shapeInferGeneric(const std::vector<ov::StaticShape>& input_shapes,
|
||||
uint32_t input_value_port_mask) const {
|
||||
// collect input values
|
||||
std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>> input_values;
|
||||
if (input_value_port_mask) {
|
||||
const auto & iranks = shapeInference->get_input_ranks();
|
||||
for (size_t port = 0; port < iranks.size(); port++) {
|
||||
if (input_value_port_mask & (1 << port)) {
|
||||
const auto& memPtr = getParentEdgesAtPort(port)[0]->getMemory();
|
||||
|
||||
for (size_t i = 0; i < opToShapeInfer->get_input_size(); i++) {
|
||||
if (!dynamic_cast<ngraph::opset1::Constant *>(opToShapeInfer->get_input_node_ptr(i))) {
|
||||
opToShapeInfer->get_input_tensor(i).set_partial_shape(shapes[i].toPartialShape());
|
||||
ov::Shape shape(memPtr.getStaticDims());
|
||||
|
||||
// use scalar shape {} instead of {1} if required by shapeInference
|
||||
if (iranks[port] == 0) {
|
||||
shape = ov::Shape();
|
||||
}
|
||||
|
||||
input_values[port] = std::make_shared<ngraph::runtime::HostTensor>(
|
||||
InferenceEngine::details::convertPrecision(memPtr.getDesc().getPrecision()),
|
||||
shape,
|
||||
memPtr.GetPtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opToShapeInfer->validate_and_infer_types();
|
||||
// call shape inference API
|
||||
std::vector<ov::StaticShape> output_shapes = shapeInference->infer(input_shapes, input_values);
|
||||
|
||||
std::vector<VectorDims> newOutputShapes(opToShapeInfer->get_output_size());
|
||||
for (size_t i = 0; i < newOutputShapes.size(); i++) {
|
||||
const auto &partShape = opToShapeInfer->get_output_partial_shape(i);
|
||||
if (partShape.is_dynamic()) {
|
||||
std::ostringstream errorMessage;
|
||||
errorMessage << "Can't compute static output shape on " << i << " port for node with name: " << getName();
|
||||
errorMessage << ". Input shapes = ( ";
|
||||
for (size_t in = 0; in < opToShapeInfer->get_input_size(); in++) {
|
||||
errorMessage << in << " port = " << opToShapeInfer->get_input_partial_shape(in) << ", ";
|
||||
}
|
||||
errorMessage << "). Output shapes = ( ";
|
||||
for (size_t out = 0; out < opToShapeInfer->get_output_size(); out++) {
|
||||
errorMessage << out << " port = " << opToShapeInfer->get_output_partial_shape(out) << ", ";
|
||||
}
|
||||
errorMessage << ")";
|
||||
IE_THROW(NotImplemented) << errorMessage.str();
|
||||
std::vector<VectorDims> result(output_shapes.size());
|
||||
std::transform(output_shapes.begin(), output_shapes.end(), result.begin(), [](const ov::StaticShape& s) {
|
||||
return s.to_shape();
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNNode::shapeInferGeneric(const std::vector<Shape>& shapes,
|
||||
uint32_t input_value_port_mask) const {
|
||||
std::vector<ov::StaticShape> input_shapes;
|
||||
|
||||
input_shapes.reserve(shapes.size());
|
||||
for (size_t i = 0; i < shapes.size(); i++)
|
||||
input_shapes.emplace_back(shapes[i].getStaticDims());
|
||||
|
||||
return shapeInferGeneric(input_shapes, input_value_port_mask);
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNNode::shapeInferGeneric(uint32_t input_value_port_mask) const {
|
||||
std::vector<ov::StaticShape> input_shapes;
|
||||
const auto & iranks = shapeInference->get_input_ranks();
|
||||
|
||||
input_shapes.reserve(iranks.size());
|
||||
|
||||
for (size_t port = 0; port < iranks.size(); port++) {
|
||||
if (iranks[port] == 0) {
|
||||
input_shapes.emplace_back();
|
||||
} else {
|
||||
input_shapes.emplace_back(getParentEdgesAtPort(port)[0]->getMemory().getStaticDims());
|
||||
}
|
||||
|
||||
newOutputShapes[i] = partShape.get_shape();
|
||||
}
|
||||
return newOutputShapes;
|
||||
|
||||
return shapeInferGeneric(input_shapes, input_value_port_mask);
|
||||
}
|
||||
|
||||
void MKLDNNNode::updateLastInputDims() {
|
||||
@ -1496,16 +1514,3 @@ bool MKLDNNNode::canFuseSimpleOperation(const MKLDNNNodePtr& node) const {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MKLDNNNode::createShapeInferSubgraph(const std::shared_ptr<ngraph::Node>& op) {
|
||||
ngraph::OutputVector inputsForShapeInfer;
|
||||
for (size_t i = 0; i < inputShapes.size(); i++) {
|
||||
if (dynamic_cast<ngraph::opset1::Constant *>(op->get_input_node_ptr(i))) {
|
||||
inputsForShapeInfer.push_back(op->get_input_node_ptr(i)->clone_with_new_inputs(ngraph::OutputVector{}));
|
||||
} else {
|
||||
inputsForShapeInfer.push_back(std::make_shared<ngraph::opset1::Parameter>(op->get_input_element_type(i),
|
||||
op->get_input_partial_shape(i)));
|
||||
}
|
||||
}
|
||||
opToShapeInfer = op->clone_with_new_inputs(inputsForShapeInfer);
|
||||
}
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include "memory_desc/cpu_memory_desc.h"
|
||||
#include "cache/multi_cache.h"
|
||||
|
||||
#include <utils/shape_inference/static_shape.hpp>
|
||||
#include <utils/shape_inference/shape_inference.hpp>
|
||||
|
||||
namespace MKLDNNPlugin {
|
||||
|
||||
using MKLDNNNodePtr = std::shared_ptr<MKLDNNNode>;
|
||||
@ -750,7 +753,8 @@ protected:
|
||||
|
||||
bool inputShapesModified() const;
|
||||
virtual bool needShapeInfer() const;
|
||||
std::vector<VectorDims> shapeInferGeneric(const std::vector<Shape>& inputDims) const;
|
||||
std::vector<VectorDims> shapeInferGeneric(const std::vector<Shape>& inputDims, uint32_t value_port_mask = 0) const;
|
||||
std::vector<VectorDims> shapeInferGeneric(uint32_t value_port_mask = 0) const;
|
||||
virtual std::vector<VectorDims> shapeInfer() const;
|
||||
// TODO [DS] : make pure after all nodes will be support dynamic shapes
|
||||
virtual void executeDynamicImpl(mkldnn::stream strm) {
|
||||
@ -770,7 +774,7 @@ protected:
|
||||
|
||||
std::vector<VectorDims> lastInputDims = {};
|
||||
|
||||
std::shared_ptr<ngraph::Node> opToShapeInfer;
|
||||
std::shared_ptr<IShapeInfer> shapeInference;
|
||||
|
||||
private:
|
||||
std::vector<MKLDNNEdgeWeakPtr> parentEdges;
|
||||
@ -797,8 +801,6 @@ private:
|
||||
|
||||
bool isEdgesEmpty(const std::vector<MKLDNNEdgeWeakPtr>& edges) const;
|
||||
|
||||
void createShapeInferSubgraph(const std::shared_ptr<ngraph::Node>& op);
|
||||
|
||||
template <class PD, class D, typename FPD>
|
||||
typename std::enable_if<!std::is_same<FPD, bool>::value, PD>::type
|
||||
createPd(MKLDNNDescriptor desc) {
|
||||
@ -817,11 +819,23 @@ private:
|
||||
enum LOOK { LOOK_UP = 1, LOOK_DOWN = 2 };
|
||||
ConstantType checkConstant(LOOK look, std::vector<MKLDNNNodePtr>& checkNodes);
|
||||
|
||||
std::vector<VectorDims> shapeInferGeneric(const std::vector<ov::StaticShape>& input_shapes,
|
||||
uint32_t input_value_port_mask) const;
|
||||
|
||||
#ifdef CPU_DEBUG_CAPS
|
||||
friend class Verbose;
|
||||
#endif
|
||||
};
|
||||
|
||||
constexpr uint64_t PortMask(int n) {
|
||||
return 1 << n;
|
||||
}
|
||||
|
||||
template <class... T>
|
||||
constexpr uint64_t PortMask(int n, T... rest) {
|
||||
return PortMask(rest...) | (1 << n);
|
||||
}
|
||||
|
||||
class MKLDNNNode::NodesFactory : public openvino::cc::Factory<Type,
|
||||
MKLDNNNode*(const std::shared_ptr<ngraph::Node>& op,
|
||||
const mkldnn::engine &,
|
||||
|
@ -96,6 +96,10 @@ void MKLDNNBatchToSpaceNode::initSupportedPrimitiveDescriptors() {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNBatchToSpaceNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(1, 2, 3));
|
||||
}
|
||||
|
||||
static std::vector<size_t> getShape5D(const SizeVector &shape) {
|
||||
std::vector<size_t> shape5D(5, 1);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
void execute(mkldnn::stream strm) override;
|
||||
bool created() const override;
|
||||
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
bool needPrepareParams() const override { return false; };
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
|
||||
|
@ -182,29 +182,7 @@ bool MKLDNNBroadcastNode::needShapeInfer() const {
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNBroadcastNode::shapeInfer() const {
|
||||
ngraph::OutputVector inputsForShapeInfer {
|
||||
std::make_shared<ov::op::v0::Parameter>(opToShapeInfer->get_input_element_type(INPUT_DATA_IDX),
|
||||
getParentEdgesAtPort(INPUT_DATA_IDX)[0]->getMemory().GetShape().toPartialShape()),
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::Type_t::i32,
|
||||
getParentEdgesAtPort(TARGET_SHAPE_IDX)[0]->getMemory().GetShape().getStaticDims(),
|
||||
getParentEdgesAtPort(TARGET_SHAPE_IDX)[0]->getMemory().GetPtr())
|
||||
};
|
||||
if (opToShapeInfer->get_input_size() > AXES_MAPPING_IDX) {
|
||||
inputsForShapeInfer.push_back(std::make_shared<ov::op::v0::Constant>(ov::element::Type_t::i32,
|
||||
getParentEdgesAtPort(AXES_MAPPING_IDX)[0]->getMemory().GetShape().getStaticDims(),
|
||||
getParentEdgesAtPort(AXES_MAPPING_IDX)[0]->getMemory().GetPtr()));
|
||||
}
|
||||
const auto localShapeInferOp = opToShapeInfer->clone_with_new_inputs(inputsForShapeInfer);
|
||||
|
||||
localShapeInferOp->validate_and_infer_types();
|
||||
|
||||
std::vector<VectorDims> newOutputShapes(outputShapes.size());
|
||||
for (size_t i = 0lu; i < newOutputShapes.size(); i++) {
|
||||
const auto &partShape = localShapeInferOp->get_output_partial_shape(i);
|
||||
newOutputShapes[i] = partShape.get_shape();
|
||||
}
|
||||
|
||||
return newOutputShapes;
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(TARGET_SHAPE_IDX, AXES_MAPPING_IDX));
|
||||
}
|
||||
|
||||
bool MKLDNNBroadcastNode::isExecutable() const {
|
||||
|
@ -1066,15 +1066,10 @@ void MKLDNNConvolutionNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
}
|
||||
|
||||
void MKLDNNConvolutionNode::updatePadding() {
|
||||
//update padding. TODO [DS] : rewrite when the final shape inference interface is available
|
||||
//update padding.
|
||||
if (isDynamicNode() && autoPadding) {
|
||||
if (auto convolutionOp = ov::as_type_ptr<ov::op::v1::Convolution>(opToShapeInfer)) {
|
||||
paddingL = convolutionOp->get_pads_begin();
|
||||
paddingR = convolutionOp->get_pads_end();
|
||||
} else if (auto groupConvolutionOp = ov::as_type_ptr<ov::op::v1::GroupConvolution>(opToShapeInfer)) {
|
||||
paddingL = groupConvolutionOp->get_pads_begin();
|
||||
paddingR = groupConvolutionOp->get_pads_end();
|
||||
}
|
||||
paddingL = shapeInference->get_pads_begin();
|
||||
paddingR = shapeInference->get_pads_end();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,26 +224,6 @@ bool MKLDNNDeconvolutionNode::canFuse(const MKLDNNNodePtr& node) const {
|
||||
return (fusedWith.empty() && node->canBePerformedAsScaleShift(this));
|
||||
}
|
||||
|
||||
void MKLDNNDeconvolutionNode::initPadding(std::shared_ptr<ngraph::Node> op, const Shape &inDims, const std::vector<int32_t>& outSpDims) {
|
||||
std::vector<ov::StaticShape> input_shapes{inDims.getStaticDims(), getWeightDims()};
|
||||
ov::StaticShape output_shape_input;
|
||||
if (externOutShape) {
|
||||
IE_ASSERT(outSpDims.size() == getInputShapeAtPort(2).getStaticDims()[0]);
|
||||
input_shapes.push_back({outSpDims.size()});
|
||||
for (size_t i = 0; i < outSpDims.size(); i++) {
|
||||
output_shape_input.push_back(outSpDims[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (getAlgorithm() == DeconvolutionCommon) {
|
||||
auto deconv = ngraph::as_type_ptr<ngraph::op::v1::ConvolutionBackpropData>(op);
|
||||
IE_ASSERT(ov::op::v1::resolve_auto_pad_for_shape_back_prop(deconv.get(), paddingL, paddingR, input_shapes, output_shape_input, 2, 2));
|
||||
} else if (getAlgorithm() == DeconvolutionGrouped) {
|
||||
auto deconv = ngraph::as_type_ptr<ngraph::op::v1::GroupConvolutionBackpropData>(op);
|
||||
IE_ASSERT(ov::op::v1::resolve_auto_pad_for_shape_back_prop(deconv.get(), paddingL, paddingR, input_shapes, output_shape_input, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<VectorDims, VectorDims> MKLDNNDeconvolutionNode::makeDummyInOutShape() {
|
||||
auto inShape = MemoryDescUtils::makeDummyShape(getInputShapeAtPort(0));
|
||||
auto outShape = getOutputShapeAtPort(0);
|
||||
@ -276,8 +256,9 @@ std::pair<VectorDims, VectorDims> MKLDNNDeconvolutionNode::makeDummyInOutShape()
|
||||
|
||||
inShape = Shape(inputDims);
|
||||
}
|
||||
initPadding(opToShapeInfer, inShape, lastOutputSpatialDims);
|
||||
outShape = Shape(shapeInferInternal(inShape.getStaticDims(), lastOutputSpatialDims));
|
||||
paddingL = shapeInference->get_pads_begin();
|
||||
paddingR = shapeInference->get_pads_end();
|
||||
}
|
||||
return {inShape.getStaticDims(), outShape.getStaticDims()};
|
||||
}
|
||||
@ -464,8 +445,7 @@ VectorDims MKLDNNDeconvolutionNode::shapeInferInternal(const VectorDims &inDims,
|
||||
outSpDims.data())});
|
||||
}
|
||||
|
||||
std::vector<ov::StaticShape> outputShapes(1);
|
||||
shape_inference(opToShapeInfer.get(), inputShapes, outputShapes, inputValues);
|
||||
std::vector<ov::StaticShape> outputShapes = shapeInference->infer(inputShapes, inputValues);
|
||||
|
||||
return outputShapes.back().to_shape();
|
||||
}
|
||||
@ -592,7 +572,8 @@ void MKLDNNDeconvolutionNode::prepareParams() {
|
||||
}
|
||||
pAttrLocal = pAttr;
|
||||
if (autoPad || externOutShape) {
|
||||
initPadding(opToShapeInfer, inMemoryDesc->getShape(), externOutShape ? readOutputSpatialDims() : std::vector<int32_t>{});
|
||||
paddingL = shapeInference->get_pads_begin();
|
||||
paddingR = shapeInference->get_pads_end();
|
||||
}
|
||||
initPaddingR(inMemoryDesc->getShape(), outMemoryDesc->getShape());
|
||||
} else {
|
||||
|
@ -1137,10 +1137,8 @@ void MKLDNNDeformableConvolutionNode::execute(mkldnn::stream strm) {
|
||||
}
|
||||
|
||||
void MKLDNNDeformableConvolutionNode::updatePadding() {
|
||||
//update padding. TODO [DS] : rewrite when the final shape inference interface is available
|
||||
if (isDynamicNode() && autoPadding) {
|
||||
auto defConvNodeBase = std::dynamic_pointer_cast<ngraph::op::util::DeformableConvolutionBase>(opToShapeInfer);
|
||||
defConvAttr.padL = defConvNodeBase->get_pads_begin();
|
||||
defConvAttr.padL = shapeInference->get_pads_begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,10 @@ void MKLDNNEmbeddingSegmentsSumNode::getIndices(int embIndex, const int*& indice
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNEmbeddingSegmentsSumNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(NUM_SEGMENTS_IDX));
|
||||
}
|
||||
|
||||
void MKLDNNEmbeddingSegmentsSumNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
|
||||
protected:
|
||||
void prepareParams() override;
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
|
||||
private:
|
||||
|
@ -2044,33 +2044,8 @@ bool MKLDNNInterpolateNode::needShapeInfer() const {
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNInterpolateNode::shapeInfer() const {
|
||||
std::vector<ov::StaticShape> input_shapes = {
|
||||
getParentEdgesAtPort(DATA_ID)[0]->getMemory().GetShape().getStaticDims(),
|
||||
getParentEdgesAtPort(TARGET_SHAPE_ID)[0]->getMemory().GetShape().getStaticDims(),
|
||||
getParentEdgesAtPort(SCALES_ID)[0]->getMemory().GetShape().getStaticDims()
|
||||
};
|
||||
|
||||
const size_t port = shapeCalcMode == InterpolateShapeCalcMode::sizes ? TARGET_SHAPE_ID : SCALES_ID;
|
||||
const auto &memory = getParentEdgesAtPort(port)[0]->getMemory();
|
||||
std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>> input_values = {
|
||||
{port, std::make_shared<ngraph::runtime::HostTensor>(InferenceEngine::details::convertPrecision(memory.getDesc().getPrecision()),
|
||||
memory.getStaticDims(), memory.GetPtr())}
|
||||
};
|
||||
|
||||
if (getParentEdges().size() > AXES_ID) {
|
||||
const auto &memory = getParentEdgesAtPort(AXES_ID)[0]->getMemory();
|
||||
input_shapes.push_back(memory.getStaticDims());
|
||||
input_values.insert({3, std::make_shared<ngraph::runtime::HostTensor>(InferenceEngine::details::convertPrecision(memory.getDesc().getPrecision()),
|
||||
memory.getStaticDims(), memory.GetPtr())});
|
||||
}
|
||||
|
||||
std::vector<ov::StaticShape> output_shapes = {{}};
|
||||
shape_inference(opToShapeInfer.get(), input_shapes, output_shapes, input_values);
|
||||
|
||||
std::vector<VectorDims> result(output_shapes.size());
|
||||
std::transform(output_shapes.begin(), output_shapes.end(), result.begin(), [](const ov::StaticShape& s){ return s.to_shape(); });
|
||||
|
||||
return result;
|
||||
return shapeInferGeneric(PortMask(port, AXES_ID));
|
||||
}
|
||||
|
||||
void MKLDNNInterpolateNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
|
@ -331,6 +331,10 @@ void MKLDNNPadNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNPadNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(PADS_BEGIN_ID, PADS_END_ID));
|
||||
}
|
||||
|
||||
static inline size_t parallel_init(size_t start, size_t nDims, const VectorDims& dims, VectorDims& indexes) {
|
||||
for (int j = nDims - 1; j >= 0; j--) {
|
||||
indexes[j] = start % dims[j];
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
bool isExecutable() const override;
|
||||
|
||||
protected:
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
|
||||
private:
|
||||
|
@ -297,32 +297,6 @@ void MKLDNNPoolingNode::getSupportedDescriptors() {
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::vector<ptrdiff_t>, std::vector<ptrdiff_t>> MKLDNNPoolingNode::getPaddingFromNode(std::shared_ptr<ov::Node> node) const {
|
||||
const auto convertPadding = [](const VectorDims &newPads) {
|
||||
std::vector<ptrdiff_t> pads(newPads.size());
|
||||
for (int i = 0; i < newPads.size(); i++) {
|
||||
pads[i] = static_cast<ptrdiff_t>(newPads[i]);
|
||||
}
|
||||
return pads;
|
||||
};
|
||||
|
||||
VectorDims padsBegin, padsEnd;
|
||||
if (isMaxPool8) {
|
||||
const auto pool = ov::as_type_ptr<const ov::op::v8::MaxPool>(opToShapeInfer);
|
||||
padsBegin = pool->get_pads_begin();
|
||||
padsEnd = pool->get_pads_end();
|
||||
} else if (getAlgorithm() == PoolingMax) {
|
||||
const auto pool = ov::as_type_ptr<const ov::op::v1::MaxPool>(opToShapeInfer);
|
||||
padsBegin = pool->get_pads_begin();
|
||||
padsEnd = pool->get_pads_end();
|
||||
} else if (getAlgorithm() == PoolingAvg) {
|
||||
const auto pool = ov::as_type_ptr<const ov::op::v1::AvgPool>(opToShapeInfer);
|
||||
padsBegin = pool->get_pads_begin();
|
||||
padsEnd = pool->get_pads_end();
|
||||
}
|
||||
return {convertPadding(padsBegin), convertPadding(padsEnd)};
|
||||
}
|
||||
|
||||
void MKLDNNPoolingNode::prepareParams() {
|
||||
const NodeDesc *selected_pd = getSelectedPrimitiveDescriptor();
|
||||
if (selected_pd == nullptr)
|
||||
@ -343,7 +317,8 @@ void MKLDNNPoolingNode::prepareParams() {
|
||||
|
||||
if (isDynamicNode()) {
|
||||
if (auto_pad) {
|
||||
std::tie(data_pad_begin, data_pad_end) = getPaddingFromNode(opToShapeInfer);
|
||||
data_pad_begin = shapeInference->get_pads_begin();
|
||||
data_pad_end = shapeInference->get_pads_end();
|
||||
}
|
||||
initEffectiveAttributes(inDesc->getShape(), outDesc->getShape());
|
||||
}
|
||||
@ -462,7 +437,8 @@ void MKLDNNPoolingNode::createDescriptor(const std::vector<MemoryDescPtr> &input
|
||||
auto outDims = shapeInferGeneric({Shape(inDesc->getShape().getStaticDims())});
|
||||
outDesc = outDesc->cloneWithNewDims(outDims[0]);
|
||||
if (auto_pad) {
|
||||
std::tie(data_pad_begin, data_pad_end) = getPaddingFromNode(opToShapeInfer);
|
||||
data_pad_begin = shapeInference->get_pads_begin();
|
||||
data_pad_end = shapeInference->get_pads_end();
|
||||
}
|
||||
initEffectiveAttributes(inDesc->getShape(), outDesc->getShape());
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ protected:
|
||||
private:
|
||||
void setPostOps(mkldnn::primitive_attr &attr, bool initWeights = false) const;
|
||||
|
||||
std::pair<std::vector<ptrdiff_t>, std::vector<ptrdiff_t>> getPaddingFromNode(std::shared_ptr<ov::Node> node) const;
|
||||
void initEffectiveAttributes(const Shape &inDims, const Shape &outDims);
|
||||
mkldnn::algorithm getPoolingAlgorithm() const;
|
||||
std::shared_ptr<mkldnn::pooling_v2_forward::desc> createDescriptorInternal(const mkldnn::memory::desc& in_candidate,
|
||||
|
@ -83,6 +83,10 @@ void MKLDNNRangeNode::initSupportedPrimitiveDescriptors() {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNRangeNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(RANGE_START, RANGE_LIMIT, RANGE_DELTA));
|
||||
}
|
||||
|
||||
void MKLDNNRangeNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ public:
|
||||
bool created() const override;
|
||||
bool needPrepareParams() const override {return false;};
|
||||
bool needShapeInfer() const override {return false;};
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
static bool isSupportedOperation(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept;
|
||||
|
||||
|
@ -1868,6 +1868,10 @@ bool MKLDNNReduceNode::isExecutable() const {
|
||||
return !isInputTensorAtPortEmpty(REDUCE_DATA);
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNReduceNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(REDUCE_INDEXES));
|
||||
}
|
||||
|
||||
void MKLDNNReduceNode::prepareParams() {
|
||||
src_dims = getParentEdgesAtPort(REDUCE_DATA)[0]->getMemory().getDesc().getShape().getDims();
|
||||
std::vector<int> reduce_axes;
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
void createPrimitive() override;
|
||||
bool created() const override;
|
||||
void execute(mkldnn::stream strm) override;
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
bool canFuse(const MKLDNNNodePtr& node) const override;
|
||||
bool canBeInPlace() const override {
|
||||
|
@ -74,40 +74,8 @@ void MKLDNNReferenceNode::execute(mkldnn::stream strm) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [DS]: rewrite after new shape infer will be added
|
||||
std::vector<VectorDims> MKLDNNReferenceNode::shapeInfer() const {
|
||||
ngraph::OutputVector inputsForShapeInfer;
|
||||
for (size_t i = 0; i < opToShapeInfer->get_input_size(); i++) {
|
||||
const auto &mem = getParentEdgesAtPort(i)[0]->getMemory();
|
||||
const auto dims = opToShapeInfer->get_input_partial_shape(i).rank().get_length() == 0 ? VectorDims{} : mem.getStaticDims();
|
||||
inputsForShapeInfer.push_back(std::make_shared<ngraph::opset1::Constant>(InferenceEngine::details::convertPrecision(mem.getDesc().getPrecision()),
|
||||
dims,
|
||||
mem.GetPtr()));
|
||||
}
|
||||
|
||||
const auto localShapeInferOp = opToShapeInfer->clone_with_new_inputs(inputsForShapeInfer);
|
||||
localShapeInferOp->validate_and_infer_types();
|
||||
|
||||
std::vector<VectorDims> newOutputShapes(outputShapes.size());
|
||||
for (size_t i = 0; i < newOutputShapes.size(); i++) {
|
||||
const auto &partShape = localShapeInferOp->get_output_partial_shape(i);
|
||||
if (partShape.is_dynamic()) {
|
||||
std::ostringstream errorMessage;
|
||||
errorMessage << "Can't compute static output shape on " << i << " port for node with name: " << getName();
|
||||
errorMessage << ". Input shapes = ( ";
|
||||
for (size_t in = 0; in < opToShapeInfer->get_input_size(); in++) {
|
||||
errorMessage << in << " port = " << opToShapeInfer->get_input_partial_shape(in) << ", ";
|
||||
}
|
||||
errorMessage << "). Output shapes = ( ";
|
||||
for (size_t out = 0; out < opToShapeInfer->get_output_size(); out++) {
|
||||
errorMessage << out << " port = " << opToShapeInfer->get_output_partial_shape(out) << ", ";
|
||||
}
|
||||
errorMessage << ")";
|
||||
IE_THROW(NotImplemented) << errorMessage.str();
|
||||
}
|
||||
newOutputShapes[i] = partShape.get_shape();
|
||||
}
|
||||
return newOutputShapes;
|
||||
return MKLDNNNode::shapeInferGeneric(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void MKLDNNReferenceNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
|
@ -75,7 +75,6 @@ bool MKLDNNReshapeNode::needShapeInfer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO [DS]: rewrite after new shape infer will be added
|
||||
std::vector<VectorDims> MKLDNNReshapeNode::shapeInfer() const {
|
||||
const auto &memPtr = getParentEdgesAtPort(1)[0]->getMemory();
|
||||
|
||||
@ -86,16 +85,7 @@ std::vector<VectorDims> MKLDNNReshapeNode::shapeInfer() const {
|
||||
lastSecondInputValues[i] = sndInput[i];
|
||||
}
|
||||
|
||||
std::vector<ov::StaticShape> input_shapes = {getParentEdgesAtPort(0)[0]->getMemory().GetShape().getStaticDims(), memPtr.getStaticDims()};
|
||||
std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>> input_values = {
|
||||
{1, std::make_shared<ngraph::runtime::HostTensor>(ngraph::element::Type_t::i32, memPtr.getStaticDims(), memPtr.GetPtr())}
|
||||
};
|
||||
std::vector<ov::StaticShape> output_shapes = {{}};
|
||||
shape_inference(opToShapeInfer.get(), input_shapes, output_shapes, input_values);
|
||||
|
||||
std::vector<VectorDims> result(output_shapes.size());
|
||||
std::transform(output_shapes.begin(), output_shapes.end(), result.begin(), [](const ov::StaticShape& s){ return s.to_shape(); });
|
||||
return result;
|
||||
return shapeInferGeneric(PortMask(1));
|
||||
}
|
||||
|
||||
void MKLDNNReshapeNode::getSupportedDescriptors() {
|
||||
|
@ -97,6 +97,10 @@ void MKLDNNSpaceToBatchNode::initSupportedPrimitiveDescriptors() {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNSpaceToBatchNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(1, 2, 3));
|
||||
}
|
||||
|
||||
static std::vector<size_t> getShape5D(const SizeVector &shape) {
|
||||
std::vector<size_t> shape5D(5, 1);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
void execute(mkldnn::stream strm) override;
|
||||
bool created() const override;
|
||||
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
bool needPrepareParams() const override { return false; };
|
||||
void executeDynamicImpl(mkldnn::stream strm) override;
|
||||
|
||||
|
@ -239,6 +239,10 @@ bool MKLDNNSplitNode::needPrepareParams() const {
|
||||
return MKLDNNNode::inputShapesModified();
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNSplitNode::shapeInfer() const {
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(1, 2));
|
||||
}
|
||||
|
||||
void MKLDNNSplitNode::prepareParams() {
|
||||
const auto &srcMemPtr = getParentEdgesAtPort(0)[0]->getMemoryPtr();
|
||||
if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr()) {
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
|
||||
bool needPrepareParams() const override;
|
||||
void prepareParams() override;
|
||||
std::vector<VectorDims> shapeInfer() const override;
|
||||
void executeDynamicImpl(mkldnn::stream strm) override { execute(strm); }
|
||||
|
||||
private:
|
||||
|
@ -123,23 +123,7 @@ bool MKLDNNTileNode::needShapeInfer() const {
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNTileNode::shapeInfer() const {
|
||||
ngraph::OutputVector inputsForShapeInfer {
|
||||
std::make_shared<ov::op::v0::Parameter>(opToShapeInfer->get_input_element_type(TILE_INPUT),
|
||||
getParentEdgesAtPort(TILE_INPUT)[0]->getMemory().GetShape().toPartialShape()),
|
||||
std::make_shared<ov::op::v0::Constant>(ov::element::Type_t::i32,
|
||||
getParentEdgesAtPort(TILE_REPEATS)[0]->getMemory().GetShape().getStaticDims(),
|
||||
getParentEdgesAtPort(TILE_REPEATS)[0]->getMemory().GetPtr())
|
||||
};
|
||||
const auto localShapeInferOp = opToShapeInfer->clone_with_new_inputs(inputsForShapeInfer);
|
||||
|
||||
localShapeInferOp->validate_and_infer_types();
|
||||
|
||||
std::vector<VectorDims> newOutputShapes(outputShapes.size());
|
||||
for (size_t i = 0lu; i < newOutputShapes.size(); i++) {
|
||||
const auto &partShape = localShapeInferOp->get_output_partial_shape(i);
|
||||
newOutputShapes[i] = partShape.get_shape();
|
||||
}
|
||||
return newOutputShapes;
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(TILE_REPEATS));
|
||||
}
|
||||
|
||||
void MKLDNNTileNode::executeDynamicImpl(mkldnn::stream strm) {
|
||||
|
@ -167,39 +167,7 @@ bool MKLDNNTopKNode::needShapeInfer() const {
|
||||
}
|
||||
|
||||
std::vector<VectorDims> MKLDNNTopKNode::shapeInfer() const {
|
||||
if (dynamic_cast<ngraph::opset1::Constant*>(opToShapeInfer->get_input_node_ptr(1))) {
|
||||
return MKLDNNNode::shapeInfer();
|
||||
}
|
||||
|
||||
opToShapeInfer->get_input_tensor(0).set_partial_shape(getParentEdgesAtPort(0)[0]->getMemory().getDesc().getShape().toPartialShape());
|
||||
|
||||
const auto& kMemory = getParentEdgesAtPort(1)[0]->getMemory();
|
||||
const auto ngPrecision = InferenceEngine::details::convertPrecision(kMemory.getDesc().getPrecision());
|
||||
const auto kConst = ngraph::opset1::Constant::create(ngPrecision, VectorDims{}, kMemory.GetPtr());
|
||||
|
||||
const auto localShapeInferOp = opToShapeInfer->clone_with_new_inputs({ opToShapeInfer->input_value(0), kConst });
|
||||
localShapeInferOp->validate_and_infer_types();
|
||||
|
||||
std::vector<VectorDims> newOutputShapes(outputShapes.size());
|
||||
for (size_t i = 0; i < newOutputShapes.size(); ++i) {
|
||||
const auto& pShape = localShapeInferOp->get_output_partial_shape(i);
|
||||
if (pShape.is_dynamic()) {
|
||||
std::ostringstream errorMessage;
|
||||
errorMessage << "Can't compute static output shape on " << i << " port for node with name: " << getName();
|
||||
errorMessage << ". Input shapes = ( ";
|
||||
for (size_t in = 0; in < opToShapeInfer->get_input_size(); in++) {
|
||||
errorMessage << in << " port = " << opToShapeInfer->get_input_partial_shape(in) << ", ";
|
||||
}
|
||||
errorMessage << "). Output shapes = ( ";
|
||||
for (size_t out = 0; out < opToShapeInfer->get_output_size(); out++) {
|
||||
errorMessage << out << " port = " << opToShapeInfer->get_output_partial_shape(out) << ", ";
|
||||
}
|
||||
errorMessage << ")";
|
||||
IE_THROW(NotImplemented) << errorMessage.str();
|
||||
}
|
||||
newOutputShapes[i] = pShape.get_shape();
|
||||
}
|
||||
return newOutputShapes;
|
||||
return MKLDNNNode::shapeInferGeneric(PortMask(1));
|
||||
}
|
||||
|
||||
template <class Compare1, template <typename> class Compare2>
|
||||
|
@ -14,14 +14,23 @@
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
|
||||
#include "assign_shape_inference.hpp"
|
||||
#include "bucketize_shape_inference.hpp"
|
||||
#include "convolution_shape_inference.hpp"
|
||||
#include "ctc_greedy_decoder_seq_len_shape_inference.hpp"
|
||||
#include "ctc_greedy_decoder_shape_inference.hpp"
|
||||
#include "ctc_loss_shape_inference.hpp"
|
||||
#include "detection_output_shape_inference.hpp"
|
||||
#include "einsum_shape_inference.hpp"
|
||||
#include "embedding_segments_sum_shape_inference.hpp"
|
||||
#include "embeddingbag_offsets_shape_inference.hpp"
|
||||
#include "experimental_detectron_detection_output_shape_inference.hpp"
|
||||
#include "experimental_detectron_generate_proposals_shape_inference.hpp"
|
||||
#include "experimental_detectron_prior_grid_generator_shape_inference.hpp"
|
||||
#include "experimental_detectron_roi_feature_shape_inference.hpp"
|
||||
#include "experimental_detectron_topkrois_shape_inference.hpp"
|
||||
#include "extract_image_patches_shape_inference.hpp"
|
||||
#include "fake_quantize.hpp"
|
||||
#include "fft_base_shape_inference.hpp"
|
||||
#include "gather_elements_shape_inference.hpp"
|
||||
#include "gather_shape_inference.hpp"
|
||||
#include "gather_tree_shape_inference.hpp"
|
||||
@ -46,226 +55,507 @@
|
||||
#include "bucketize_shape_inference.hpp"
|
||||
#include "embedding_segments_sum_shape_inference.hpp"
|
||||
#include "embeddingbag_offsets_shape_inference.hpp"
|
||||
#include "experimental_detectron_roi_feature_shape_inference.hpp"
|
||||
#include "pad_shape_inference.hpp"
|
||||
#include "proposal_shape_inference.hpp"
|
||||
#include "range_shape_inference.hpp"
|
||||
#include "read_value_shape_inference.hpp"
|
||||
#include "reduce_shape_inference.hpp"
|
||||
#include "region_yolo_shape_inference.hpp"
|
||||
#include "reorg_yolo_shape_inference.hpp"
|
||||
#include "split_shape_inference.hpp"
|
||||
#include "topk_shape_inference.hpp"
|
||||
#include "variadic_split_shape_inference.hpp"
|
||||
#include "einsum_shape_inference.hpp"
|
||||
#include "strided_slice_shape_inference.hpp"
|
||||
#include "experimental_detectron_generate_proposals_shape_inference.hpp"
|
||||
#include "reverse_sequence_shape_inference.hpp"
|
||||
#include "roi_align_shape_inference.hpp"
|
||||
#include "roll_shape_inference.hpp"
|
||||
#include "proposal_shape_inference.hpp"
|
||||
#include "detection_output_shape_inference.hpp"
|
||||
#include "scatter_elements_update_shape_inference.hpp"
|
||||
#include "scatter_nd_base_shape_inference.hpp"
|
||||
#include "select_shape_inference.hpp"
|
||||
#include "shape_inference.hpp"
|
||||
#include "shape_nodes.hpp"
|
||||
#include "shuffle_channels_shape_inference.hpp"
|
||||
#include "split_shape_inference.hpp"
|
||||
#include "broadcast_shape_inference.hpp"
|
||||
#include "static_shape.hpp"
|
||||
#include "strided_slice_shape_inference.hpp"
|
||||
#include "tile_shape_inference.hpp"
|
||||
#include "topk_shape_inference.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "variadic_split_shape_inference.hpp"
|
||||
|
||||
void shape_inference(ov::Node* op,
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
std::vector<ov::StaticShape>& output_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) {
|
||||
if (auto node = ov::as_type<ov::opset8::Convolution>(op)) {
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
bool status = resolve_auto_pad_for_shape(node, pads_begin, pads_end, input_shapes, 2, 2);
|
||||
auto shapeInfer = make_shape_inference(op->shared_from_this());
|
||||
output_shapes = shapeInfer->infer(input_shapes, constant_data);
|
||||
}
|
||||
|
||||
class entryBase : public IShapeInfer {
|
||||
public:
|
||||
entryBase(std::shared_ptr<ov::Node> node) : node(node) {
|
||||
for (size_t i = 0; i < node->get_input_size(); i++) {
|
||||
const auto& shape = node->get_input_partial_shape(i);
|
||||
if (shape.rank().is_static()) {
|
||||
input_ranks.push_back(shape.rank().get_length());
|
||||
} else {
|
||||
input_ranks.push_back(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ov::CoordinateDiff& get_pads_begin() override {
|
||||
OPENVINO_ASSERT(false, "entryBase do not support get_pads_begin() by default.");
|
||||
}
|
||||
|
||||
const ov::CoordinateDiff& get_pads_end() override {
|
||||
OPENVINO_ASSERT(false, "entryBase do not support get_pads_end() by default.");
|
||||
}
|
||||
|
||||
const std::vector<int64_t>& get_input_ranks() override {
|
||||
return input_ranks;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<int64_t> input_ranks;
|
||||
std::shared_ptr<ov::Node> node;
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
class entryIO : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = static_cast<OP*>(node.get());
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
shape_infer(op, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
class entryIOC : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = static_cast<OP*>(node.get());
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
shape_infer(op, input_shapes, output_shapes, constant_data);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
class entryCopy : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = node.get();
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
copy_shape_infer(op, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
class entryFirstPassthrough : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = node.get();
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
first_input_passthrough_infer(op, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
class entryEltwise : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = node.get();
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
eltwise_shape_infer(op, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
class entryFallback : public entryBase {
|
||||
public:
|
||||
std::shared_ptr<ov::Node> local_op_default;
|
||||
|
||||
entryFallback(std::shared_ptr<ov::Node> node) : entryBase(node) {
|
||||
ngraph::OutputVector new_inputs;
|
||||
auto op = node.get();
|
||||
for (size_t i = 0; i < op->get_input_size(); ++i) {
|
||||
if (dynamic_cast<ov::opset1::Constant*>(op->get_input_node_ptr(i))) {
|
||||
new_inputs.push_back(op->get_input_node_ptr(i)->clone_with_new_inputs(ov::OutputVector{}));
|
||||
} else {
|
||||
new_inputs.push_back(std::make_shared<ov::opset1::Parameter>(op->get_input_element_type(i),
|
||||
op->get_input_partial_shape(i)));
|
||||
}
|
||||
}
|
||||
|
||||
local_op_default = op->clone_with_new_inputs(new_inputs);
|
||||
}
|
||||
|
||||
virtual void post_validate_and_infer_types(const std::shared_ptr<ov::Node>& local_op) {}
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = node.get();
|
||||
std::vector<ov::StaticShape> output_shapes;
|
||||
|
||||
std::shared_ptr<ov::Node> local_op;
|
||||
if (!constant_data.empty()) {
|
||||
ngraph::OutputVector new_inputs;
|
||||
for (size_t i = 0; i < op->get_input_size(); ++i) {
|
||||
if (constant_data.count(i)) {
|
||||
new_inputs.push_back(std::make_shared<ov::opset1::Constant>(constant_data.at(i)));
|
||||
} else if (dynamic_cast<ov::opset1::Constant*>(op->get_input_node_ptr(i))) {
|
||||
new_inputs.push_back(op->get_input_node_ptr(i)->clone_with_new_inputs(ov::OutputVector{}));
|
||||
} else {
|
||||
new_inputs.push_back(std::make_shared<ov::opset1::Parameter>(op->get_input_element_type(i),
|
||||
input_shapes[i].to_partial_shape()));
|
||||
}
|
||||
}
|
||||
local_op = op->clone_with_new_inputs(new_inputs);
|
||||
} else {
|
||||
local_op = local_op_default;
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
for (size_t i = 0; i < local_op->get_input_size(); i++) {
|
||||
if (dynamic_cast<ov::opset1::Parameter*>(local_op->get_input_node_ptr(i))) {
|
||||
local_op->get_input_tensor(i).set_partial_shape(input_shapes[i].to_partial_shape());
|
||||
}
|
||||
}
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
local_op->validate_and_infer_types();
|
||||
|
||||
output_shapes.resize(local_op->get_output_size());
|
||||
for (size_t i = 0; i < output_shapes.size(); ++i) {
|
||||
const auto& partial_shape = local_op->get_output_partial_shape(i);
|
||||
|
||||
if (partial_shape.is_dynamic()) {
|
||||
std::ostringstream errorMessage;
|
||||
errorMessage << "Can't compute static output shape on " << i
|
||||
<< " port for node with name: " << op->get_name();
|
||||
errorMessage << ". Input shapes = ( ";
|
||||
for (size_t in = 0; in < op->get_input_size(); in++) {
|
||||
errorMessage << in << " port = " << op->get_input_partial_shape(in) << ", ";
|
||||
}
|
||||
errorMessage << "). Output shapes = ( ";
|
||||
for (size_t out = 0; out < op->get_output_size(); out++) {
|
||||
errorMessage << out << " port = " << op->get_output_partial_shape(out) << ", ";
|
||||
}
|
||||
errorMessage << ")";
|
||||
OPENVINO_ASSERT(false, errorMessage.str());
|
||||
}
|
||||
|
||||
output_shapes[i] = ov::StaticShape(partial_shape.to_shape());
|
||||
}
|
||||
|
||||
post_validate_and_infer_types(local_op);
|
||||
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
static inline ov::CoordinateDiff convertPadding(const ov::CoordinateDiff& newPads) {
|
||||
return newPads;
|
||||
}
|
||||
|
||||
static inline ov::CoordinateDiff convertPadding(const ov::Shape& newPads) {
|
||||
std::vector<ptrdiff_t> pads(newPads.size());
|
||||
for (int i = 0; i < newPads.size(); i++) {
|
||||
pads[i] = static_cast<ptrdiff_t>(newPads[i]);
|
||||
}
|
||||
return pads;
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
class entryFallbackWithPadding : public entryFallback {
|
||||
public:
|
||||
using entryFallback::entryFallback;
|
||||
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
|
||||
const ov::CoordinateDiff& get_pads_begin() override {
|
||||
return pads_begin;
|
||||
}
|
||||
const ov::CoordinateDiff& get_pads_end() override {
|
||||
return pads_end;
|
||||
}
|
||||
|
||||
void post_validate_and_infer_types(const std::shared_ptr<ov::Node>& local_op) override {
|
||||
auto node = dynamic_cast<OP*>(local_op.get());
|
||||
OPENVINO_ASSERT(node);
|
||||
pads_begin = convertPadding(node->get_pads_begin());
|
||||
pads_end = convertPadding(node->get_pads_end());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
class entryInterpolate : public entryBase {
|
||||
public:
|
||||
using entryBase::entryBase;
|
||||
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
std::vector<size_t> pads_begin, pads_end;
|
||||
auto op = static_cast<OP*>(node.get());
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
correct_pads_attr(op, pads_begin, pads_end, input_shapes);
|
||||
shape_infer(op, pads_begin, pads_end, input_shapes, output_shapes, constant_data);
|
||||
return output_shapes;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
class entryConv : public entryBase {
|
||||
public:
|
||||
entryConv(std::shared_ptr<OP> node, bool is_grouped) : entryBase(node), is_grouped(is_grouped) {}
|
||||
const ov::CoordinateDiff& get_pads_begin() override {
|
||||
return pads_begin;
|
||||
}
|
||||
const ov::CoordinateDiff& get_pads_end() override {
|
||||
return pads_end;
|
||||
}
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
auto op = static_cast<OP*>(node.get());
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
bool status = resolve_auto_pad_for_shape(op, pads_begin, pads_end, input_shapes, 2, is_grouped ? 3 : 2);
|
||||
OPENVINO_ASSERT(status,
|
||||
"Convolution shape inference doesn't have enough information to calculate static shapes");
|
||||
shape_infer(node, pads_begin, pads_end, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset8::GroupConvolution>(op)) {
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
bool status = resolve_auto_pad_for_shape(node, pads_begin, pads_end, input_shapes, 2, 3);
|
||||
OPENVINO_ASSERT(status,
|
||||
"GroupConvolution shape inference doesn't have enough information to calculate static shapes");
|
||||
shape_infer(node, pads_begin, pads_end, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset8::ConvolutionBackpropData>(op)) {
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
shape_infer(op, pads_begin, pads_end, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
|
||||
protected:
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
bool is_grouped;
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
class entryConvBackprop : public entryBase {
|
||||
public:
|
||||
entryConvBackprop(std::shared_ptr<OP> node, bool is_grouped) : entryBase(node), is_grouped(is_grouped) {}
|
||||
const ov::CoordinateDiff& get_pads_begin() override {
|
||||
return pads_begin;
|
||||
}
|
||||
const ov::CoordinateDiff& get_pads_end() override {
|
||||
return pads_end;
|
||||
}
|
||||
std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) override {
|
||||
ov::StaticShape output_shape_input;
|
||||
if (node->get_input_size() == 3)
|
||||
auto op = static_cast<OP*>(node.get());
|
||||
std::vector<ov::StaticShape> output_shapes(op->get_output_size());
|
||||
if (op->get_input_size() == 3)
|
||||
get_data_as_shape<ov::StaticShape>(2, op, output_shape_input, constant_data);
|
||||
bool status =
|
||||
resolve_auto_pad_for_shape_back_prop(node, pads_begin, pads_end, input_shapes, output_shape_input, 2, 2);
|
||||
bool status = resolve_auto_pad_for_shape_back_prop(op,
|
||||
pads_begin,
|
||||
pads_end,
|
||||
input_shapes,
|
||||
output_shape_input,
|
||||
2,
|
||||
is_grouped ? 3 : 2);
|
||||
OPENVINO_ASSERT(
|
||||
status,
|
||||
"ConvolutionBackpropData shape inference doesn't have enough information to calculate static shapes");
|
||||
shape_infer(node, pads_begin, pads_end, output_shape_input, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset8::GroupConvolutionBackpropData>(op)) {
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
ov::StaticShape output_shape_input;
|
||||
if (node->get_input_size() == 3)
|
||||
get_data_as_shape<ov::StaticShape>(2, op, output_shape_input, constant_data);
|
||||
bool status =
|
||||
resolve_auto_pad_for_shape_back_prop(node, pads_begin, pads_end, input_shapes, output_shape_input, 2, 3);
|
||||
OPENVINO_ASSERT(
|
||||
status,
|
||||
"GroupConvolutionBackpropData shape inference doesn't have enough information to calculate static shapes");
|
||||
shape_infer(node, pads_begin, pads_end, output_shape_input, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::op::util::ArithmeticReductionKeepDims>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::op::util::LogicalReductionKeepDims>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (ov::is_type<ov::op::util::UnaryElementwiseArithmetic>(op) ||
|
||||
ov::is_type<ov::opset1::Convert>(op) || ov::is_type<ov::opset1::Clamp>(op) ||
|
||||
ov::is_type<ov::opset1::GRN>(op) || ov::is_type<ov::opset1::LRN>(op) ||
|
||||
ov::is_type<ov::opset1::LogicalNot>(op) || ov::is_type<ov::opset4::Mish>(op) ||
|
||||
ov::is_type<ov::opset2::MVN>(op) || ov::is_type<ov::opset6::MVN>(op) ||
|
||||
ov::is_type<ov::opset1::PRelu>(op) || ov::is_type<ov::opset1::Relu>(op) ||
|
||||
ov::is_type<ov::opset4::Swish>(op) || ov::is_type<ov::opset1::Elu>(op) ||
|
||||
ov::is_type<ov::opset1::Softmax>(op) || ov::is_type<ov::opset8::Softmax>(op) ||
|
||||
ov::is_type<ov::opset5::Round>(op)) {
|
||||
copy_shape_infer(node, input_shapes, output_shapes);
|
||||
shape_infer(op, pads_begin, pads_end, output_shape_input, input_shapes, output_shapes);
|
||||
return output_shapes;
|
||||
}
|
||||
|
||||
protected:
|
||||
ov::CoordinateDiff pads_begin, pads_end;
|
||||
bool is_grouped;
|
||||
};
|
||||
|
||||
template <typename OP>
|
||||
std::shared_ptr<entryIOC<OP>> make_shared_entryIOC(std::shared_ptr<OP> node) {
|
||||
return std::make_shared<entryIOC<OP>>(node);
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
std::shared_ptr<entryIO<OP>> make_shared_entryIO(std::shared_ptr<OP> node) {
|
||||
return std::make_shared<entryIO<OP>>(node);
|
||||
}
|
||||
|
||||
std::shared_ptr<IShapeInfer> make_shape_inference(const std::shared_ptr<ngraph::Node>& op) {
|
||||
if (auto node = ov::as_type_ptr<ov::opset8::Convolution>(op)) {
|
||||
return std::make_shared<entryConv<ov::opset8::Convolution>>(node, false);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset8::GroupConvolution>(op)) {
|
||||
return std::make_shared<entryConv<ov::opset8::GroupConvolution>>(node, true);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset8::ConvolutionBackpropData>(op)) {
|
||||
return std::make_shared<entryConvBackprop<ov::opset8::ConvolutionBackpropData>>(node, false);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset8::GroupConvolutionBackpropData>(op)) {
|
||||
return std::make_shared<entryConvBackprop<ov::opset8::GroupConvolutionBackpropData>>(node, true);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::util::ArithmeticReductionKeepDims>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::util::LogicalReductionKeepDims>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (ov::is_type<ov::op::util::UnaryElementwiseArithmetic>(op) || ov::is_type<ov::opset1::Convert>(op) ||
|
||||
ov::is_type<ov::opset1::Clamp>(op) || ov::is_type<ov::opset1::GRN>(op) ||
|
||||
ov::is_type<ov::opset1::LogicalNot>(op) || ov::is_type<ov::opset4::Mish>(op) ||
|
||||
ov::is_type<ov::opset2::MVN>(op) || ov::is_type<ov::opset1::Relu>(op) ||
|
||||
ov::is_type<ov::opset1::Elu>(op) || ov::is_type<ov::opset1::Softmax>(op) ||
|
||||
ov::is_type<ov::opset8::Softmax>(op) || ov::is_type<ov::opset5::Round>(op)) {
|
||||
return std::make_shared<entryCopy>(op);
|
||||
} else if (ov::is_type<ov::opset6::MVN>(op) || ov::is_type<ov::opset1::LRN>(op) ||
|
||||
ov::is_type<ov::opset1::PRelu>(op) || ov::is_type<ov::opset4::Swish>(op)) {
|
||||
return std::make_shared<entryFirstPassthrough>(op);
|
||||
} else if (ov::is_type<ov::op::util::BinaryElementwiseArithmetic>(op) ||
|
||||
ov::is_type<ov::op::util::BinaryElementwiseComparison>(op) ||
|
||||
ov::is_type<ov::op::util::BinaryElementwiseLogical>(op)) {
|
||||
eltwise_shape_infer(op, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::FakeQuantize>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Reshape>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Squeeze>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Unsqueeze>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::ShapeOf>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::ShapeOf>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ExperimentalDetectronDetectionOutput>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::TopK>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset3::Bucketize>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::EmbeddingSegmentsSum>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset3::EmbeddingBagOffsetsSum>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ExperimentalDetectronROIFeatureExtractor>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Pad>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset4::Range>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Range>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::RegionYolo>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset2::ReorgYolo>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Split>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::VariadicSplit>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset7::Einsum>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::StridedSlice>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset3::Assign>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::Assign>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ExperimentalDetectronPriorGridGenerator>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::LSTMCell>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::LSTMCell>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::ReadValue>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ReadValue>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::Tile>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ExperimentalDetectronTopKROIs>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset4::Interpolate>(op)) {
|
||||
std::vector<size_t> pads_begin, pads_end;
|
||||
correct_pads_attr(node, pads_begin, pads_end, input_shapes);
|
||||
shape_infer(node, pads_begin, pads_end, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Interpolate>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset3::ScatterElementsUpdate>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset4::ScatterNDUpdate>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::GatherElements>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::op::util::GatherBase>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::GatherTree>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::OneHot>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset4::CTCLoss>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset7::DFT>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset7::IDFT>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset6::CTCGreedyDecoderSeqLen>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset6::CTCGreedyDecoder>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::ExtractImagePatches>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::ReverseSequence>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset7::Roll>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset6::ExperimentalDetectronGenerateProposalsSingleImage>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset4::Proposal>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Proposal>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset3::ROIAlign>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::DetectionOutput>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset8::DetectionOutput>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Select>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::ShuffleChannels>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset2::BatchToSpace>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset2::SpaceToBatch>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::DepthToSpace>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset1::SpaceToDepth>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes);
|
||||
} else if (auto node = ov::as_type<ov::opset4::Broadcast>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
} else if (auto node = ov::as_type<ov::opset1::Broadcast>(op)) {
|
||||
shape_infer(node, input_shapes, output_shapes, constant_data);
|
||||
return std::make_shared<entryEltwise>(op);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::FakeQuantize>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Reshape>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Squeeze>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Unsqueeze>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::ShapeOf>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::ShapeOf>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ExperimentalDetectronDetectionOutput>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::TopK>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::Bucketize>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::EmbeddingSegmentsSum>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::EmbeddingBagOffsetsSum>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ExperimentalDetectronROIFeatureExtractor>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Pad>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::Range>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Range>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::RegionYolo>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset2::ReorgYolo>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Split>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::VariadicSplit>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset7::Einsum>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::StridedSlice>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::Assign>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::Assign>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ExperimentalDetectronPriorGridGenerator>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::LSTMCell>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::LSTMCell>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::ReadValue>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ReadValue>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::Tile>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ExperimentalDetectronTopKROIs>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::Interpolate>(op)) {
|
||||
return std::make_shared<entryInterpolate<ov::opset4::Interpolate>>(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Interpolate>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::ScatterElementsUpdate>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::ScatterNDUpdate>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::GatherElements>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::util::GatherBase>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::GatherTree>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::OneHot>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::CTCLoss>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset7::DFT>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset7::IDFT>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::CTCGreedyDecoderSeqLen>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::CTCGreedyDecoder>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::ExtractImagePatches>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::ReverseSequence>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset7::Roll>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset6::ExperimentalDetectronGenerateProposalsSingleImage>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::Proposal>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Proposal>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset3::ROIAlign>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::DetectionOutput>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset8::DetectionOutput>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Select>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::ShuffleChannels>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset2::BatchToSpace>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset2::SpaceToBatch>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::DepthToSpace>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::SpaceToDepth>(op)) {
|
||||
return make_shared_entryIO(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset4::Broadcast>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::opset1::Broadcast>(op)) {
|
||||
return make_shared_entryIOC(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::v8::MaxPool>(op)) {
|
||||
return std::make_shared<entryFallbackWithPadding<ov::op::v8::MaxPool>>(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::v1::MaxPool>(op)) {
|
||||
return std::make_shared<entryFallbackWithPadding<ov::op::v1::MaxPool>>(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::v1::AvgPool>(op)) {
|
||||
return std::make_shared<entryFallbackWithPadding<ov::op::v1::AvgPool>>(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::v1::DeformableConvolution>(op)) {
|
||||
return std::make_shared<entryFallbackWithPadding<ov::op::v1::DeformableConvolution>>(node);
|
||||
} else if (auto node = ov::as_type_ptr<ov::op::v8::DeformableConvolution>(op)) {
|
||||
return std::make_shared<entryFallbackWithPadding<ov::op::v8::DeformableConvolution>>(node);
|
||||
} else {
|
||||
ngraph::OutputVector new_inputs;
|
||||
for (size_t i = 0; i < op->get_input_size(); ++i) {
|
||||
if (constant_data.count(i)) {
|
||||
new_inputs.push_back(std::make_shared<ov::opset1::Constant>(constant_data.at(i)));
|
||||
} else {
|
||||
new_inputs.push_back(std::make_shared<ov::opset1::Parameter>(op->get_input_element_type(i),
|
||||
input_shapes[i].to_partial_shape()));
|
||||
}
|
||||
}
|
||||
const auto local_op = op->clone_with_new_inputs(new_inputs);
|
||||
local_op->validate_and_infer_types();
|
||||
|
||||
output_shapes.resize(op->get_output_size());
|
||||
for (size_t i = 0; i < output_shapes.size(); ++i) {
|
||||
const auto& partial_shape = local_op->get_output_partial_shape(i);
|
||||
OPENVINO_ASSERT(
|
||||
partial_shape.is_static(),
|
||||
"On device shape infer shouldn't support default shape infer for nodes with internal dynamism");
|
||||
output_shapes[i] = ov::StaticShape(partial_shape.to_shape());
|
||||
}
|
||||
return std::make_shared<entryFallback>(op);
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvino/core/node.hpp>
|
||||
#include <ngraph/runtime/host_tensor.hpp>
|
||||
#include <openvino/core/core.hpp>
|
||||
#include <openvino/core/node.hpp>
|
||||
|
||||
#include "static_shape.hpp"
|
||||
|
||||
|
||||
|
||||
void shape_inference(ov::Node* op,
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
std::vector<ov::StaticShape>& output_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {});
|
||||
|
||||
class IShapeInfer {
|
||||
public:
|
||||
virtual std::vector<ov::StaticShape> infer(
|
||||
const std::vector<ov::StaticShape>& input_shapes,
|
||||
const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data) = 0;
|
||||
|
||||
// infer may generate padding as by-product, these APIs is designed to retrieve them back
|
||||
virtual const ov::CoordinateDiff& get_pads_begin() = 0;
|
||||
virtual const ov::CoordinateDiff& get_pads_end() = 0;
|
||||
|
||||
virtual const std::vector<int64_t>& get_input_ranks() = 0;
|
||||
};
|
||||
|
||||
std::shared_ptr<IShapeInfer> make_shape_inference(const std::shared_ptr<ngraph::Node>& op);
|
||||
|
Loading…
Reference in New Issue
Block a user