[CPU] Gemm node: supported precisions U8 and I8 and added tests

This commit is contained in:
Anton Voronov
2020-06-03 20:01:58 +03:00
committed by Alexander Peskov
parent 92e5e010b9
commit 629ca3a5d8
11 changed files with 403 additions and 36 deletions

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "single_layer_tests/mat_mul.hpp"
using namespace LayerTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> inputPrecisions = {
InferenceEngine::Precision::FP32
};
const std::vector<std::vector<size_t>> shapesA = {
{1, 4, 5, 6}
};
const std::vector<std::vector<size_t>> shapesB = {
{1, 4, 6, 4}
};
INSTANTIATE_TEST_CASE_P(MatMul, MatMulTest,
::testing::Combine(
::testing::ValuesIn(inputPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
MatMulTest::getTestCaseName);
} // namespace

View File

@@ -0,0 +1,60 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "subgraph_tests/quantized_mat_mul.hpp"
using namespace LayerTestsDefinitions;
using namespace ngraph::helpers;
namespace {
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32
};
const std::vector<std::vector<size_t>> shapesA = {
{1, 4, 5, 6}
};
const std::vector<std::vector<size_t>> shapesB = {
{1, 4, 6, 4}
};
const std::vector<size_t> levels = {256};
const std::vector<QuantizationGranularity> granularity = {Pertensor};
const auto quantParams_i8i8 = ::testing::Combine(
::testing::ValuesIn(levels),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::I8)
);
const auto quantParams_u8i8 = ::testing::Combine(
::testing::ValuesIn(levels),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::U8)
);
INSTANTIATE_TEST_CASE_P(QuantMatMul_i8i8, QuantMatMulTest,
::testing::Combine(
quantParams_i8i8,
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
QuantMatMulTest::getTestCaseName);
INSTANTIATE_TEST_CASE_P(QuantMatMul_u8i8, QuantMatMulTest,
::testing::Combine(
quantParams_u8i8,
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
QuantMatMulTest::getTestCaseName);
} // namespace

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "functional_test_utils/layer_test_utils.hpp"
typedef std::tuple<
InferenceEngine::Precision,
InferenceEngine::SizeVector,
InferenceEngine::SizeVector,
LayerTestsUtils::TargetDevice
> MatMulLayerTestParamsSet;
namespace LayerTestsDefinitions {
class MatMulTest : public testing::WithParamInterface<MatMulLayerTestParamsSet>, public LayerTestsUtils::LayerTestsCommon {
public:
static std::string getTestCaseName(const testing::TestParamInfo<MatMulLayerTestParamsSet> &obj);
protected:
void SetUp() override;
};
} // namespace LayerTestsDefinitions

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "functional_test_utils/layer_test_utils.hpp"
typedef std::tuple<
size_t,
ngraph::helpers::QuantizationGranularity,
InferenceEngine::Precision> QuantParams;
typedef std::tuple<
QuantParams,
InferenceEngine::Precision,
InferenceEngine::SizeVector,
InferenceEngine::SizeVector,
LayerTestsUtils::TargetDevice> QuantMatMulLayerTestParamsSet;
namespace LayerTestsDefinitions {
class QuantMatMulTest : public testing::WithParamInterface<QuantMatMulLayerTestParamsSet>, public LayerTestsUtils::LayerTestsCommon {
public:
static std::string getTestCaseName(const testing::TestParamInfo<QuantMatMulLayerTestParamsSet> &obj);
protected:
void SetUp() override;
};
} // namespace LayerTestsDefinitions

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "single_layer_tests/mat_mul.hpp"
#include "ngraph_functions/builders.hpp"
namespace LayerTestsDefinitions {
std::string MatMulTest::getTestCaseName(const testing::TestParamInfo<MatMulLayerTestParamsSet> &obj) {
InferenceEngine::Precision netPrecision;
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
std::string targetDevice;
std::tie(netPrecision, inputShape0, inputShape1, targetDevice) = obj.param;
std::ostringstream result;
result << "IS0=" << CommonTestUtils::vec2str(inputShape0) << "_";
result << "IS1=" << CommonTestUtils::vec2str(inputShape1) << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
void MatMulTest::SetUp() {
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
auto netPrecision = InferenceEngine::Precision::UNSPECIFIED;
std::tie(netPrecision, inputShape0, inputShape1, targetDevice) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto params = ngraph::builder::makeParams(ngPrc, {inputShape0, inputShape1});
auto paramOuts = ngraph::helpers::convert2OutputVector(
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
auto MatMul = std::dynamic_pointer_cast<ngraph::opset3::MatMul>(
ngraph::builder::makeMatMul(paramOuts[0], paramOuts[1]));
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(MatMul)};
function = std::make_shared<ngraph::Function>(results, params, "MatMul");
}
TEST_P(MatMulTest, CompareWithRefs) {
Run();
};
} // namespace LayerTestsDefinitions

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "subgraph_tests/quantized_mat_mul.hpp"
#include "ngraph_functions/builders.hpp"
using ngraph::helpers::QuantizationGranularity;
namespace LayerTestsDefinitions {
std::string QuantMatMulTest::getTestCaseName(const testing::TestParamInfo<QuantMatMulLayerTestParamsSet> &obj) {
QuantParams quantParams;
InferenceEngine::Precision netPrecision;
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
std::string targetDevice;
std::tie(quantParams, netPrecision, inputShape0, inputShape1, targetDevice) = obj.param;
size_t quantLevels;
QuantizationGranularity quantGranularity;
InferenceEngine::Precision fqPrec0;
std::tie(quantLevels, quantGranularity, fqPrec0) = quantParams;
std::ostringstream result;
result << "IS0=" << CommonTestUtils::vec2str(inputShape0) << "_";
result << "IS1=" << CommonTestUtils::vec2str(inputShape1) << "_";
result << "Levels=" << quantLevels << "_";
result << "QuantGranularity=" << quantGranularity << "_";
result << "fq0PRC=" << fqPrec0.name() << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
void QuantMatMulTest::SetUp() {
QuantParams quantParams;
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
auto netPrecision = InferenceEngine::Precision::UNSPECIFIED;
std::tie(quantParams, netPrecision, inputShape0, inputShape1, targetDevice) = this->GetParam();
size_t quantLevels;
QuantizationGranularity quantGranularity;
InferenceEngine::Precision fqPrec0;
std::tie(quantLevels, quantGranularity, fqPrec0) = quantParams;
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto params = ngraph::builder::makeParams(ngPrc, {inputShape0, inputShape1});
auto paramOuts = ngraph::helpers::convert2OutputVector(
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
auto makeFakeQuantizeNode = [ngPrc, quantLevels, quantGranularity](const ngraph::Output<ngraph::Node> &in,
std::vector<size_t> inputShape, InferenceEngine::Precision prec) -> std::shared_ptr<ngraph::Node> {
std::vector<size_t> dataFqConstShapes(inputShape.size(), 1);
if (quantGranularity == ngraph::helpers::Perchannel)
dataFqConstShapes[1] = inputShape[1];
size_t constDataSize = ngraph::shape_size(dataFqConstShapes);
std::vector<float> inputLowData(constDataSize), inputHighData(constDataSize), outputLowData(constDataSize), outputHighData(constDataSize);
for (int i = 0; i < constDataSize; i++) {
inputLowData[i] = 0;
inputHighData[i] = 255;
outputLowData[i] = prec == InferenceEngine::Precision::I8 ? -128 : 0;
outputHighData[i] = prec == InferenceEngine::Precision::I8 ? 127 : 255;
}
return ngraph::builder::makeFakeQuantize(in, ngPrc, quantLevels, dataFqConstShapes, inputLowData, inputHighData, outputLowData, outputHighData);
};
auto dataFq0 = makeFakeQuantizeNode(paramOuts[0], inputShape0, fqPrec0);
auto dataFq1 = makeFakeQuantizeNode(paramOuts[1], inputShape1, InferenceEngine::Precision::I8);
auto MatMul = std::dynamic_pointer_cast<ngraph::opset3::MatMul>(
ngraph::builder::makeMatMul(dataFq0, dataFq1));
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(MatMul)};
function = std::make_shared<ngraph::Function>(results, params, "QuantMatMul");
}
TEST_P(QuantMatMulTest, CompareWithRefs) {
Run();
};
} // namespace LayerTestsDefinitions

View File

@@ -89,6 +89,8 @@ InferenceEngine::details::LowPrecisionTransformer LayerTransformation::getLowPre
return transformer;
}
IE_SUPPRESS_DEPRECATED_START
void LayerTransformation::checkPrecisions(const InferenceEngine::CNNLayer& layer, const InferenceEngine::Precision& expectedPrecision) {
for (const InferenceEngine::DataWeakPtr insDataWeak : layer.insData) {
const InferenceEngine::DataPtr insData = insDataWeak.lock();
@@ -153,6 +155,8 @@ void LayerTransformation::checkPrecisions(
checkPrecision(layer, expectedOutputPrecisions, 0, false);
}
IE_SUPPRESS_DEPRECATED_END
std::pair<float, float> LayerTransformation::getQuantizationInterval(const InferenceEngine::Precision precision) {
const bool unsignedInterval = precision == InferenceEngine::Precision::U8;
const float low = unsignedInterval ? 0.f : -128.f;

View File

@@ -239,5 +239,8 @@ std::shared_ptr<Node> makeShuffleChannels(const ngraph::Output<Node> &in,
int axis,
int group);
std::shared_ptr<Node> makeMatMul(const Output<Node>& A,
const Output<Node>& B);
} // namespace builder
} // namespace ngraph

View File

@@ -0,0 +1,16 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "ngraph_functions/builders.hpp"
namespace ngraph {
namespace builder {
std::shared_ptr<Node> makeMatMul(const Output<Node>& A,
const Output<Node>& B) {
return std::make_shared<ngraph::opset3::MatMul>(A, B);
}
} // namespace builder
} // namespace ngraph