Change FW levels type from int to size_t (#5218)

This commit is contained in:
Nadezhda Ageeva
2021-04-16 11:36:23 +03:00
committed by GitHub
parent 1f145923f5
commit e170785c1f
10 changed files with 176 additions and 47 deletions

View File

@@ -36,7 +36,7 @@ enum DnnActivationType : uint8_t {
struct FakeQuantizeParams {
int8_t set;
int32_t levels;
size_t levels;
// if input is per-channel quantization - input pointers contains per-channel ranges
int8_t inputPerChannel;
float* input_low;

View File

@@ -28,7 +28,7 @@ class GNAFakeQuantizeLayer {
DnnActivation parseAsActivation() const {
DnnActivation fqActivation;
fqActivation.fqParams.levels = fqLayer->GetParamAsInt("levels");
fqActivation.fqParams.levels = fqLayer->GetParamAsSizeT("levels");
auto inputShape = getShapeForRange(fqLayer, 1);
auto outputShape = getShapeForRange(fqLayer, 3);
@@ -64,7 +64,7 @@ class GNAFakeQuantizeLayer {
}
int32_t getLevels() {
return fqLayer->GetParamAsInt("levels");
return fqLayer->GetParamAsSizeT("levels");
}
std::pair<std::vector<float>, std::vector<float>> getInputRange() {

View File

@@ -300,6 +300,23 @@ public:
*/
unsigned int GetParamAsUInt(const char* param) const;
/**
* @brief Returns an size_t value for the given parameter or returns the default value
*
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return An size_t value for the specified parameter
*/
size_t GetParamAsSizeT(const char* param, size_t def) const;
/**
* @brief Returns an size_t value for the given parameter
*
* @param param Name of the layer parameter
* @return An size_t value for the specified parameter
*/
size_t GetParamAsSizeT(const char* param) const;
/**
* @brief Returns a vector of unsigned int values for the given parameter or returns the default value
*
@@ -1953,7 +1970,7 @@ public:
/**
* @brief The number of quantization levels
*/
int levels = 1;
size_t levels = 1;
/**
* @brief Creates a new QuantizeLayer instance.

View File

@@ -1033,7 +1033,7 @@ void QuantizeValidator::parseParams(CNNLayer* layer) {
IE_THROW() << "Layer is not instance of QuantizeLayer class";
}
casted->levels = casted->GetParamAsInt("levels", 1);
casted->levels = casted->GetParamAsSizeT("levels", 1);
if (casted->levels <= 1) {
IE_THROW() << layer->name << ": Incorrect value for parameter levels = " << casted->levels

View File

@@ -178,10 +178,10 @@ std::vector<int> CNNLayer::GetParamAsInts(const char* param) const {
unsigned int CNNLayer::GetParamAsUInt(const char* param, unsigned int def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name +
". Value " + val + " cannot be casted to int.";
". Value " + val + " cannot be casted to unsigned int.";
try {
int value = std::stoi(val);
if (value < 0) {
long value = std::stol(val);
if ((value < 0) || (value > std::numeric_limits<unsigned int>::max())) {
IE_THROW() << message;
}
return static_cast<unsigned int>(value);
@@ -195,8 +195,8 @@ unsigned int CNNLayer::GetParamAsUInt(const char* param) const {
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name +
". Value " + val + " cannot be casted to unsigned int.";
try {
int value = std::stoi(val);
if (value < 0) {
long value = std::stol(val);
if ((value < 0) || (value > std::numeric_limits<unsigned int>::max())) {
IE_THROW() << message;
}
return static_cast<unsigned int>(value);
@@ -215,8 +215,8 @@ std::vector<unsigned int> CNNLayer::GetParamAsUInts(const char* param, std::vect
if (vals.empty()) return def;
while (getline(stream, str, ',')) {
try {
int value = std::stoi(str);
if (value < 0) {
long value = std::stol(str);
if ((value < 0) || (value > std::numeric_limits<unsigned int>::max())) {
IE_THROW() << message;
}
result.push_back(static_cast<unsigned int>(value));
@@ -233,11 +233,11 @@ std::vector<unsigned int> CNNLayer::GetParamAsUInts(const char* param) const {
std::istringstream stream(vals);
std::string str;
std::string message = "Cannot parse parameter " + std::string(param) + " " + str + " from IR for layer " +
name + ". Value " + vals + " cannot be casted to int.";
name + ". Value " + vals + " cannot be casted to unsigned int.";
while (getline(stream, str, ',')) {
try {
int value = std::stoi(str);
if (value < 0) {
long value = std::stol(str);
if ((value < 0) || (value > std::numeric_limits<unsigned int>::max())) {
IE_THROW() << message;
}
result.push_back(static_cast<unsigned int>(value));
@@ -248,6 +248,36 @@ std::vector<unsigned int> CNNLayer::GetParamAsUInts(const char* param) const {
return result;
}
size_t CNNLayer::GetParamAsSizeT(const char* param, size_t def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name +
". Value " + val + " cannot be casted to size_t.";
try {
long long value = std::stoll(val);
if ((value < 0) || (static_cast<unsigned long long>(value) > std::numeric_limits<size_t>::max())) {
IE_THROW() << message;
}
return static_cast<size_t>(value);
} catch (...) {
IE_THROW() << message;
}
}
size_t CNNLayer::GetParamAsSizeT(const char* param) const {
std::string val = GetParamAsString(param);
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name +
". Value " + val + " cannot be casted to size_t.";
try {
long long value = std::stoll(val);
if ((value < 0) || (static_cast<unsigned long long>(value) > std::numeric_limits<size_t>::max())) {
IE_THROW() << message;
}
return static_cast<size_t>(value);
} catch (...) {
IE_THROW() << message;
}
}
bool CNNLayer::GetParamAsBool(const char* param, bool def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string loweredCaseValue;

View File

@@ -122,7 +122,7 @@ private:
void executeBinarization();
void executeQuantization();
int levels = -1;
size_t levels = 0;
std::vector<float> binarizationThresholds;
std::vector<uint32_t> binarizationOutputMask;

View File

@@ -3,6 +3,7 @@
//
#include <vector>
#include <limits>
#include "subgraph_tests/quantized_mat_mul.hpp"
@@ -23,24 +24,63 @@ const std::vector<std::vector<size_t>> shapesB = {
{1, 4, 6, 4}
};
const std::vector<size_t> levels = {256};
const std::vector<QuantRange> ranges_i8 = {
{ -127, 128 }
};
const std::vector<QuantRange> ranges_u8 = {
{ 0, 255 }
};
const std::vector<QuantRange> ranges_i16 = {
{ -32768, 32767 }
};
const std::vector<QuantRange> ranges_i32 = {
{ INT32_MIN, INT32_MAX }
};
const std::vector<size_t> levels_8 = {256};
const std::vector<size_t> levels_16 = {65536};
const std::vector<size_t> levels_32 = {4294967296};
const std::vector<QuantizationGranularity> granularity = {Pertensor};
const auto quantParams_i8i8 = ::testing::Combine(
::testing::ValuesIn(levels),
const auto quantParams_i8 = ::testing::Combine(
::testing::ValuesIn(levels_8),
::testing::ValuesIn(ranges_u8),
::testing::ValuesIn(ranges_i8),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::I8)
);
const auto quantParams_u8i8 = ::testing::Combine(
::testing::ValuesIn(levels),
const auto quantParams_u8 = ::testing::Combine(
::testing::ValuesIn(levels_8),
::testing::ValuesIn(ranges_u8),
::testing::ValuesIn(ranges_u8),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::U8)
);
const auto quantParams_i16 = ::testing::Combine(
::testing::ValuesIn(levels_16),
::testing::ValuesIn(ranges_i32),
::testing::ValuesIn(ranges_i16),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::I16)
);
const auto quantParams_i32 = ::testing::Combine(
::testing::ValuesIn(levels_32),
::testing::ValuesIn(ranges_i32),
::testing::ValuesIn(ranges_i32),
::testing::ValuesIn(granularity),
::testing::Values(InferenceEngine::Precision::I32)
);
INSTANTIATE_TEST_CASE_P(smoke_QuantMatMul_i8i8, QuantMatMulTest,
::testing::Combine(
quantParams_i8i8,
quantParams_i8,
quantParams_i8,
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),
@@ -49,7 +89,18 @@ INSTANTIATE_TEST_CASE_P(smoke_QuantMatMul_i8i8, QuantMatMulTest,
INSTANTIATE_TEST_CASE_P(smoke_QuantMatMul_u8i8, QuantMatMulTest,
::testing::Combine(
quantParams_u8i8,
quantParams_u8,
quantParams_i8,
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
QuantMatMulTest::getTestCaseName);
INSTANTIATE_TEST_CASE_P(smoke_QuantMatMul_i16i32, QuantMatMulTest,
::testing::Combine(
quantParams_i16,
quantParams_i32,
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(shapesA),
::testing::ValuesIn(shapesB),

View File

@@ -13,12 +13,17 @@
namespace SubgraphTestsDefinitions {
typedef std::pair<float, float> QuantRange;
typedef std::tuple<
size_t,
QuantRange,
QuantRange,
ngraph::helpers::QuantizationGranularity,
InferenceEngine::Precision> QuantParams;
typedef std::tuple<
QuantParams,
QuantParams,
InferenceEngine::Precision,
InferenceEngine::SizeVector,

View File

@@ -10,64 +10,90 @@ namespace SubgraphTestsDefinitions {
using ngraph::helpers::QuantizationGranularity;
std::string QuantMatMulTest::getTestCaseName(const testing::TestParamInfo<QuantMatMulLayerTestParamsSet> &obj) {
QuantParams quantParams;
QuantParams quantParams0;
QuantParams quantParams1;
InferenceEngine::Precision netPrecision;
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
QuantRange inputRange0;
QuantRange inputRange1;
QuantRange outputRange0;
QuantRange outputRange1;
std::string targetDevice;
std::tie(quantParams, netPrecision, inputShape0, inputShape1, targetDevice) = obj.param;
std::tie(quantParams0, quantParams1, netPrecision, inputShape0, inputShape1, targetDevice) = obj.param;
size_t quantLevels;
QuantizationGranularity quantGranularity;
size_t quantLevels0;
size_t quantLevels1;
QuantizationGranularity quantGranularity0;
QuantizationGranularity quantGranularity1;
InferenceEngine::Precision fqPrec0;
std::tie(quantLevels, quantGranularity, fqPrec0) = quantParams;
InferenceEngine::Precision fqPrec1;
std::tie(quantLevels0, inputRange0, outputRange0, quantGranularity0, fqPrec0) = quantParams0;
std::tie(quantLevels1, inputRange1, outputRange1, quantGranularity1, fqPrec1) = quantParams1;
std::ostringstream result;
result << "IS0=" << CommonTestUtils::vec2str(inputShape0) << "_";
result << "IS1=" << CommonTestUtils::vec2str(inputShape1) << "_";
result << "Levels=" << quantLevels << "_";
result << "QuantGranularity=" << quantGranularity << "_";
result << "Levels0=" << quantLevels0 << "_";
result << "Levels1=" << quantLevels1 << "_";
result << "inputRange0=" << inputRange0.first << "_" << inputRange0.second << "_";
result << "outputRange0=" << outputRange0.first << "_" << outputRange0.second << "_";
result << "inputRange1=" << inputRange1.first << "_" << inputRange1.second << "_";
result << "outputRange1=" << outputRange1.first << "_" << outputRange1.second << "_";
result << "QuantGranularity0=" << quantGranularity0 << "_";
result << "QuantGranularity1=" << quantGranularity1 << "_";
result << "fq0PRC=" << fqPrec0.name() << "_";
result << "fq1PRC=" << fqPrec1.name() << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
void QuantMatMulTest::SetUp() {
QuantParams quantParams;
QuantParams quantParams0;
QuantParams quantParams1;
InferenceEngine::SizeVector inputShape0;
InferenceEngine::SizeVector inputShape1;
auto netPrecision = InferenceEngine::Precision::UNSPECIFIED;
std::tie(quantParams, netPrecision, inputShape0, inputShape1, targetDevice) = this->GetParam();
std::tie(quantParams0, quantParams1, netPrecision, inputShape0, inputShape1, targetDevice) = this->GetParam();
size_t quantLevels;
QuantizationGranularity quantGranularity;
size_t quantLevels0;
size_t quantLevels1;
QuantRange inputRange0;
QuantRange inputRange1;
QuantRange outputRange0;
QuantRange outputRange1;
QuantizationGranularity quantGranularity0;
QuantizationGranularity quantGranularity1;
InferenceEngine::Precision fqPrec0;
std::tie(quantLevels, quantGranularity, fqPrec0) = quantParams;
InferenceEngine::Precision fqPrec1;
std::tie(quantLevels0, inputRange0, outputRange0, quantGranularity0, fqPrec0) = quantParams0;
std::tie(quantLevels1, inputRange1, outputRange1, quantGranularity1, fqPrec1) = quantParams1;
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> {
auto makeFakeQuantizeNode = [ngPrc](size_t quantLevels, QuantRange inputRange, QuantRange outputRange,
QuantizationGranularity 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;
inputLowData[i] = inputRange.first;
inputHighData[i] = inputRange.second;
outputLowData[i] = outputRange.first;
outputHighData[i] = outputRange.second;
}
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 dataFq0 = makeFakeQuantizeNode(quantLevels0, inputRange0, outputRange0, quantGranularity0, paramOuts[0], inputShape0, fqPrec0);
auto dataFq1 = makeFakeQuantizeNode(quantLevels1, inputRange1, outputRange1, quantGranularity1, paramOuts[1], inputShape1, fqPrec1);
auto MatMul = std::dynamic_pointer_cast<ngraph::opset3::MatMul>(
ngraph::builder::makeMatMul(dataFq0, dataFq1));

View File

@@ -16,7 +16,7 @@ TEST(type_prop, fake_quantize)
const auto input_high = make_shared<op::Parameter>(element::f32, Shape{});
const auto output_low = make_shared<op::Parameter>(element::f32, Shape{});
const auto output_high = make_shared<op::Parameter>(element::f32, Shape{});
const int levels = 5;
const size_t levels = 5;
const auto fake_quantize =
make_shared<op::FakeQuantize>(data, input_low, input_high, output_low, output_high, levels);
@@ -31,7 +31,7 @@ TEST(type_prop, fake_quantize_autob)
const auto input_high = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
const auto output_low = make_shared<op::Parameter>(element::f32, Shape{4});
const auto output_high = make_shared<op::Parameter>(element::f32, Shape{});
const int levels = 5;
const size_t levels = 5;
const auto fake_quantize =
make_shared<op::FakeQuantize>(data, input_low, input_high, output_low, output_high, levels);
@@ -46,7 +46,7 @@ TEST(type_prop, fake_quantize_invalid_autob)
auto input_high = make_shared<op::Parameter>(element::f32, Shape{});
auto output_low = make_shared<op::Parameter>(element::f32, Shape{});
auto output_high = make_shared<op::Parameter>(element::f32, Shape{});
const int levels = 5;
const size_t levels = 5;
try
{
@@ -59,4 +59,4 @@ TEST(type_prop, fake_quantize_invalid_autob)
{
EXPECT_HAS_SUBSTRING(error.what(), std::string("Argument shapes are inconsistent"));
}
}
}