From e2c52d2d8a9e4572ccfbc0872d6c44c54eff46ec Mon Sep 17 00:00:00 2001 From: "Jing.Deng" Date: Thu, 10 Jun 2021 09:42:58 +0800 Subject: [PATCH] add int8 quantized unit_test for conv2d Signed-off-by: Jing.Deng --- src/tim/vx/ops/conv2d_test.cc | 207 ++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/src/tim/vx/ops/conv2d_test.cc b/src/tim/vx/ops/conv2d_test.cc index 0e49bd0..5119b60 100644 --- a/src/tim/vx/ops/conv2d_test.cc +++ b/src/tim/vx/ops/conv2d_test.cc @@ -1320,3 +1320,210 @@ TEST(Conv2d, shape_9_9_1_1_uint8_DilationQuantizedTest) { EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); EXPECT_EQ(golden, output); } + +TEST(Conv2d, shape_3_2_2_1_int8_QuantizedPerTensorTest) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + tim::vx::ShapeType input_shape({3, 2, 2, 1}); //whcn + tim::vx::ShapeType weight_shape({2, 2, 2, 2}); //whio + tim::vx::ShapeType bias_shape({weight_shape[3]}); + tim::vx::ShapeType output_shape( + {2, 1, weight_shape[3], input_shape[3]}); //whcn + + float InputMin = -63.5, InputMax = 64, WeightMin = -63.5, WeightMax = 64, + OutputMin = -63.5, OutputMax = 64; + + std::pair scalesAndZp; + + scalesAndZp = QuantizationParams(InputMin, InputMax); + std::vector scalesInput = {scalesAndZp.first}; + std::vector zeroPointsInput = {scalesAndZp.second}; + + scalesAndZp = QuantizationParams(WeightMin, WeightMax); + std::vector scalesWeight = {1}; + std::vector zeroPointsWeight = {0}; + + std::vector scalesBias = {scalesInput[0] * scalesWeight[0]}; + std::vector zeroPointsBias = {0}; + + scalesAndZp = QuantizationParams(OutputMin, OutputMax); + std::vector scalesOutput = {scalesAndZp.first}; + std::vector zeroPointsOutput = {scalesAndZp.second}; + + tim::vx::Quantization quantInput(tim::vx::QuantType::ASYMMETRIC, 2, + scalesInput, zeroPointsInput); + tim::vx::Quantization quantWeight(tim::vx::QuantType::ASYMMETRIC, 2, + scalesWeight, zeroPointsWeight); + tim::vx::Quantization quantBias(tim::vx::QuantType::ASYMMETRIC, 2, scalesBias, + zeroPointsBias); + tim::vx::Quantization quantOutput(tim::vx::QuantType::ASYMMETRIC, 2, + scalesOutput, zeroPointsOutput); + + tim::vx::TensorSpec input_spec(tim::vx::DataType::INT8, input_shape, + tim::vx::TensorAttribute::INPUT, quantInput); + tim::vx::TensorSpec weight_spec(tim::vx::DataType::INT8, weight_shape, + tim::vx::TensorAttribute::CONSTANT, + quantWeight); + tim::vx::TensorSpec bias_spec(tim::vx::DataType::INT32, bias_shape, + tim::vx::TensorAttribute::CONSTANT, quantBias); + tim::vx::TensorSpec output_spec(tim::vx::DataType::INT8, output_shape, + tim::vx::TensorAttribute::OUTPUT, + quantOutput); + + // Input data nchw + // min:-63.5 max:64 scale:0.5 Zp:-1 + std::vector input_data_float = {3, 1, -2, 4, 2, -3, + 2, -1, -3, 3, -2, -4}; + std::vector input_data = + Quantize(input_data_float, scalesInput[0], zeroPointsInput[0]); + + // weight_float_data = {1, 3, 3, 5, 2, 4, 4, 6, 7, 5, 3, 1, 8, 6, 4, 2}; + std::vector weight_data = {1, 3, 3, 5, 2, 4, 4, 6, + 7, 5, 3, 1, 8, 6, 4, 2}; + + // bias data + std::vector bias_data_float = {3, -2}; + std::vector bias_data = + Quantize(bias_data_float, scalesBias[0], zeroPointsBias[0]); + + // golden_int8_data = {61, -115, 111, -89} + // min:-63.5 max:64 scale:0.5 Zp:-1 + std::vector golden_float = {31, -57, 56, -44}; + std::vector golden = + Quantize(golden_float, scalesOutput[0], zeroPointsOutput[0]); + + auto input_tensor = graph->CreateTensor(input_spec); + auto weight_tensor = graph->CreateTensor(weight_spec, weight_data.data()); + auto bias_tensor = graph->CreateTensor(bias_spec, bias_data.data()); + auto output_tensor = graph->CreateTensor(output_spec); + + std::array ksize({weight_shape[1], weight_shape[2]}); + std::array stride({1, 1}); + std::array dilation({1, 1}); + auto padding = tim::vx::PadType::VALID; + + auto conv2d = graph->CreateOperation( + weight_shape[3], padding, ksize, stride, dilation); + (*conv2d) + .BindInput(input_tensor) + .BindInput(weight_tensor) + .BindInput(bias_tensor) + .BindOutput(output_tensor); + + EXPECT_TRUE(graph->Compile()); + + input_tensor->CopyDataToTensor(input_data.data()); + + EXPECT_TRUE(graph->Run()); + + uint32_t output_size = 1; + for (auto i : output_tensor->GetShape()) { + output_size *= i; + } + std::vector output(output_size); + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); + EXPECT_EQ(golden, output); +} + +TEST(Conv2d, shape_3_2_2_1_int8_QuantizedPerChannelTest) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + tim::vx::ShapeType input_shape({3, 2, 2, 1}); //whcn + tim::vx::ShapeType weight_shape({2, 2, 2, 2}); //whio + tim::vx::ShapeType bias_shape({weight_shape[3]}); + tim::vx::ShapeType output_shape( + {2, 1, weight_shape[3], input_shape[3]}); //whcn + + float InputMin = -63.5, InputMax = 64, WeightMin = 0, WeightMax = 0, + OutputMin = -63.5, OutputMax = 64; + + std::pair scalesAndZp; + + scalesAndZp = QuantizationParams(InputMin, InputMax); + std::vector scalesInput = {scalesAndZp.first}; + std::vector zeroPointsInput = {scalesAndZp.second}; + + scalesAndZp = QuantizationParams(WeightMin, WeightMax); + std::vector scalesWeight = {1, 2}; + std::vector zeroPointsWeight = {0, 0}; + + std::vector scalesBias = {scalesInput[0] * scalesWeight[0], + scalesInput[0] * scalesWeight[1]}; + std::vector zeroPointsBias = {0, 0}; + + scalesAndZp = QuantizationParams(OutputMin, OutputMax); + std::vector scalesOutput = {scalesAndZp.first}; + std::vector zeroPointsOutput = {scalesAndZp.second}; + + tim::vx::Quantization quantInput(tim::vx::QuantType::ASYMMETRIC, 2, + scalesInput, zeroPointsInput); + tim::vx::Quantization quantWeight(tim::vx::QuantType::SYMMETRIC_PER_CHANNEL, + 2, scalesWeight, zeroPointsWeight); + tim::vx::Quantization quantBias(tim::vx::QuantType::SYMMETRIC_PER_CHANNEL, 0, + scalesBias, zeroPointsBias); + tim::vx::Quantization quantOutput(tim::vx::QuantType::ASYMMETRIC, 2, + scalesOutput, zeroPointsOutput); + + tim::vx::TensorSpec input_spec(tim::vx::DataType::INT8, input_shape, + tim::vx::TensorAttribute::INPUT, quantInput); + tim::vx::TensorSpec weight_spec(tim::vx::DataType::INT8, weight_shape, + tim::vx::TensorAttribute::CONSTANT, + quantWeight); + tim::vx::TensorSpec bias_spec(tim::vx::DataType::INT32, bias_shape, + tim::vx::TensorAttribute::CONSTANT, quantBias); + tim::vx::TensorSpec output_spec(tim::vx::DataType::INT8, output_shape, + tim::vx::TensorAttribute::OUTPUT, + quantOutput); + + // Input data nchw + // min:-63.5 max:64 scale:0.5 Zp:-1 + std::vector input_data_float = {3, 1, -2, 4, 2, -3, + 2, -1, -3, 3, -2, -4}; + std::vector input_data = + Quantize(input_data_float, scalesInput[0], zeroPointsInput[0]); + + // weight_data_float = {1, 3, 3, 5, 2, 4, 4, 6, 7, 5, 3, 1, 8, 6, 4, 2}; + std::vector weight_data = {1, 3, 3, 5, 2, 4, 4, 6, + 4, 3, 2, 1, 4, 3, 2, 1}; + + // bias_data_float ={3, -2}; + std::vector bias_data = {6, -2}; + + // golden data + // min:-63.5 max:64 scale:0.5 Zp:-1 + std::vector golden_float = {31, -57, 64, -46}; + std::vector golden = + Quantize(golden_float, scalesOutput[0], zeroPointsOutput[0]); + + auto input_tensor = graph->CreateTensor(input_spec); + auto weight_tensor = graph->CreateTensor(weight_spec, weight_data.data()); + auto bias_tensor = graph->CreateTensor(bias_spec, bias_data.data()); + auto output_tensor = graph->CreateTensor(output_spec); + + std::array ksize({weight_shape[1], weight_shape[2]}); + std::array stride({1, 1}); + std::array dilation({1, 1}); + auto padding = tim::vx::PadType::VALID; + + auto conv2d = graph->CreateOperation( + weight_shape[3], padding, ksize, stride, dilation); + (*conv2d) + .BindInput(input_tensor) + .BindInput(weight_tensor) + .BindInput(bias_tensor) + .BindOutput(output_tensor); + + EXPECT_TRUE(graph->Compile()); + + input_tensor->CopyDataToTensor(input_data.data()); + + EXPECT_TRUE(graph->Run()); + + uint32_t output_size = 1; + for (auto i : output_tensor->GetShape()) { + output_size *= i; + } + std::vector output(output_size); + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); + EXPECT_EQ(golden, output); +}