[CPU] GRN: dynamic shapes support (#11678)

This commit is contained in:
Roman Baranchuk 2022-06-22 05:45:06 +03:00 committed by GitHub
parent dab9da25fa
commit 5cba0ae871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 170 additions and 13 deletions

View File

@ -16,10 +16,6 @@ namespace node {
bool GRN::isSupportedOperation(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept {
try {
if (isDynamicNgraphNode(op)) {
errorMessage = "Doesn't support op with dynamic shapes";
return false;
}
const auto grn = std::dynamic_pointer_cast<const ngraph::opset1::GRN>(op);
if (!grn) {
errorMessage = "Only opset1 GRN operation is supported";
@ -44,9 +40,14 @@ GRN::GRN(const std::shared_ptr<ngraph::Node>& op, const dnnl::engine& eng,
IE_THROW() << "Operation with name '" << op->get_friendly_name() <<
"' is not an instance of GRN from opset1.";
if (getOriginalInputsNumber() != 1 || getOriginalOutputsNumber() != 1)
if (inputShapes.size() != 1 || outputShapes.size() != 1)
IE_THROW() << errorPrefix << " has incorrect number of input/output edges!";
const auto dataRank = getInputShapeAtPort(0).getRank();
if (dataRank != getOutputShapeAtPort(0).getRank())
IE_THROW() << errorPrefix << " has input/output rank mismatch";
bias = grn->get_bias();
}
@ -59,17 +60,43 @@ void GRN::initSupportedPrimitiveDescriptors() {
impl_desc_type::ref_any);
}
void GRN::prepareParams() {
const auto& dataMemPtr = getParentEdgeAt(0)->getMemoryPtr();
const auto& dstMemPtr = getChildEdgeAt(0)->getMemoryPtr();
if (!dataMemPtr || !dataMemPtr->isAllocated())
IE_THROW() << errorPrefix << " has not allocated input memory";
if (!dstMemPtr || !dstMemPtr->isAllocated())
IE_THROW() << errorPrefix << " has not allocated output memory";
if (getSelectedPrimitiveDescriptor() == nullptr)
IE_THROW() << errorPrefix << " has unidentified preferable primitive descriptor";
const VectorDims& dataDims = dataMemPtr->getStaticDims();
const VectorDims& dstDims = dstMemPtr->getStaticDims();
for (size_t i = 0; i < dataDims.size(); ++i) {
if (dataDims[i] != dstDims[i])
IE_THROW() << errorPrefix << " hsd input/output tensors dimensions mismatch";
}
if (dataDims.size() > 0)
N = static_cast<int>(dataDims[0]);
if (dataDims.size() > 1)
C = static_cast<int>(dataDims[1]);
if (dataDims.size() > 2)
H = static_cast<int>(dataDims[2]);
if (dataDims.size() > 3)
W = static_cast<int>(dataDims[3]);
}
void GRN::executeDynamicImpl(dnnl::stream strm) {
execute(std::move(strm));
}
void GRN::execute(dnnl::stream strm) {
const float* src_data = reinterpret_cast<const float *>(getParentEdgeAt(0)->getMemoryPtr()->GetPtr());
float* dst_data = reinterpret_cast<float *>(getChildEdgesAtPort(0)[0]->getMemoryPtr()->GetPtr());
const auto &dims = getParentEdgeAt(0)->getMemory().getStaticDims();
int N = static_cast<int>((dims.size() > 0) ? dims[0] : 1);
int C = static_cast<int>((dims.size() > 1) ? dims[1] : 1);
int H = static_cast<int>((dims.size() > 2) ? dims[2] : 1);
int W = static_cast<int>((dims.size() > 3) ? dims[3] : 1);
parallel_for3d(N, H, W, [&](int b, int h, int w) {
double variance = 0;
for (int c = 0; c < C; c++) {

View File

@ -17,14 +17,20 @@ public:
void getSupportedDescriptors() override {};
void initSupportedPrimitiveDescriptors() override;
void createPrimitive() override {};
void execute(dnnl::stream strm) override;
bool created() const override;
void prepareParams() override;
void executeDynamicImpl(dnnl::stream strm) override;
static bool isSupportedOperation(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept;
private:
float bias = 1.0f;
int N = 1;
int C = 1;
int H = 1;
int W = 1;
std::string errorPrefix;
};

View File

@ -0,0 +1,124 @@
// Copyright (C) 2018-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "shared_test_classes/base/ov_subgraph.hpp"
#include "ngraph_functions/builders.hpp"
#include "test_utils/cpu_test_utils.hpp"
using namespace CPUTestUtils;
using namespace ov::test;
namespace CPULayerTestsDefinitions {
using GRNCPUTestParams = typename std::tuple<
ov::element::Type, // Network precision
InferenceEngine::Precision, // Input precision
InferenceEngine::Precision, // Output precision
InferenceEngine::Layout, // Input layout
InferenceEngine::Layout, // Output layout
InputShape, // Input shape
float, // Bias
std::string>; // Device name
class GRNLayerCPUTest : public testing::WithParamInterface<GRNCPUTestParams>,
virtual public SubgraphBaseTest, public CPUTestsBase {
public:
static std::string getTestCaseName(testing::TestParamInfo<GRNCPUTestParams> obj) {
ov::element::Type netPrecision;
InferenceEngine::Precision inPrc, outPrc;
InferenceEngine::Layout inLayout, outLayout;
InputShape inputShape;
float bias;
std::string targetDevice;
std::tie(netPrecision, inPrc, outPrc,
inLayout, outLayout,
inputShape,
bias,
targetDevice) = obj.param;
std::ostringstream result;
result << "IS=" << CommonTestUtils::partialShape2str({inputShape.first}) << "_";
result << "TS=";
for (const auto& item : inputShape.second) {
result << CommonTestUtils::vec2str(item) << "_";
}
result << "netPRC=" << netPrecision.get_type_name() << "_";
result << "inPRC=" << inPrc.name() << "_";
result << "outPRC=" << outPrc.name() << "_";
result << "inL=" << inLayout << "_";
result << "outL=" << outLayout << "_";
result << "bias=" << bias << "_";
result << "trgDev=" << targetDevice;
return result.str();
}
protected:
void SetUp() override {
ov::element::Type netPrecision;
InferenceEngine::Precision inPrc, outPrc;
InferenceEngine::Layout inLayout, outLayout;
InputShape inputShape;
float bias;
std::tie(netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, bias, targetDevice) = GetParam();
init_input_shapes({inputShape});
const auto paramsIn = ngraph::builder::makeDynamicParams(netPrecision, inputDynamicShapes);
const auto paramsOut = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(paramsIn));
const auto grn = std::make_shared<ngraph::opset1::GRN>(paramsOut[0], bias);
const ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(grn)};
function = std::make_shared<ngraph::Function>(results, paramsIn, "Grn");
}
};
TEST_P(GRNLayerCPUTest, CompareWithRefs) {
run();
}
namespace {
const std::vector<ov::element::Type> netPrecisions = {
ov::element::bf16,
ov::element::f16,
ov::element::f32
};
const std::vector<float> biases = {1e-6f, 0.33f, 1.1f, 2.25f, 100.25f};
const std::vector<InputShape> dataInputStaticShapes = {{{}, {{16, 24}}}, {{}, {{3, 16, 24}}}, {{}, {{1, 3, 30, 30}}}};
const std::vector<InputShape> dataInputDynamicShapes =
{{{-1, -1}, {{5, 17}, {10, 3}}}, {{3, {10, 12}, -1}, {{3, 12, 25}, {3, 10, 10}}},
{{2, -1, -1, {5, 10}}, {{2, 17, 20, 7}, {2, 10, 12, 5}}}};
INSTANTIATE_TEST_SUITE_P(smoke_GRNCPUStatic, GRNLayerCPUTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::ValuesIn(dataInputStaticShapes),
::testing::ValuesIn(biases),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
GRNLayerCPUTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_GRNCPUDynamic, GRNLayerCPUTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::ValuesIn(dataInputDynamicShapes),
::testing::ValuesIn(biases),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
GRNLayerCPUTest::getTestCaseName);
} // namespace
} // namespace CPULayerTestsDefinitions