1 // 2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #include "ParserFlatbuffersFixture.hpp" 7 8 9 TEST_SUITE("TensorflowLiteParser_DepthwiseConvolution2D") 10 { 11 struct DepthwiseConvolution2dFixture : public ParserFlatbuffersFixture 12 { DepthwiseConvolution2dFixtureDepthwiseConvolution2dFixture13 explicit DepthwiseConvolution2dFixture(const std::string& inputShape, 14 const std::string& outputShape, 15 const std::string& filterShape, 16 const std::string& filterData, 17 const std::string& strides, 18 const std::string& paddingType, 19 const std::string biasShape = "", 20 const std::string biasData = "") 21 { 22 std::string inputTensors = "[ 0, 2 ]"; 23 std::string biasTensor = ""; 24 std::string biasBuffer = ""; 25 if (biasShape.size() > 0 && biasData.size() > 0) 26 { 27 inputTensors = "[ 0, 2, 3 ]"; 28 biasTensor = R"( 29 { 30 "shape": )" + biasShape + R"( , 31 "type": "INT32", 32 "buffer": 3, 33 "name": "biasTensor", 34 "quantization": { 35 "min": [ 0.0 ], 36 "max": [ 255.0 ], 37 "scale": [ 1.0 ], 38 "zero_point": [ 0 ], 39 } 40 } )"; 41 biasBuffer = R"( 42 { "data": )" + biasData + R"(, }, )"; 43 } 44 m_JsonString = R"( 45 { 46 "version": 3, 47 "operator_codes": [ { "builtin_code": "DEPTHWISE_CONV_2D" } ], 48 "subgraphs": [ { 49 "tensors": [ 50 { 51 "shape": )" + inputShape + R"(, 52 "type": "UINT8", 53 "buffer": 0, 54 "name": "inputTensor", 55 "quantization": { 56 "min": [ 0.0 ], 57 "max": [ 255.0 ], 58 "scale": [ 1.0 ], 59 "zero_point": [ 0 ], 60 } 61 }, 62 { 63 "shape": )" + outputShape + R"(, 64 "type": "UINT8", 65 "buffer": 1, 66 "name": "outputTensor", 67 "quantization": { 68 "min": [ 0.0 ], 69 "max": [ 511.0 ], 70 "scale": [ 2.0 ], 71 "zero_point": [ 0 ], 72 } 73 }, 74 { 75 "shape": )" + filterShape + R"(, 76 "type": "UINT8", 77 "buffer": 2, 78 "name": "filterTensor", 79 "quantization": { 80 "min": [ 0.0 ], 81 "max": [ 255.0 ], 82 "scale": [ 1.0 ], 83 "zero_point": [ 0 ], 84 } 85 }, )" + biasTensor + R"( 86 ], 87 "inputs": [ 0 ], 88 "outputs": [ 1 ], 89 "operators": [ 90 { 91 "opcode_index": 0, 92 "inputs": )" + inputTensors + R"(, 93 "outputs": [ 1 ], 94 "builtin_options_type": "DepthwiseConv2DOptions", 95 "builtin_options": { 96 "padding": ")" + paddingType + R"(", 97 "stride_w": )" + strides+ R"(, 98 "stride_h": )" + strides+ R"(, 99 "depth_multiplier": 1, 100 "fused_activation_function": "NONE" 101 }, 102 "custom_options_format": "FLEXBUFFERS" 103 } 104 ], 105 } ], 106 "buffers" : [ 107 { }, 108 { }, 109 { "data": )" + filterData + R"(, }, )" 110 + biasBuffer + R"( 111 ] 112 } 113 )"; 114 SetupSingleInputSingleOutput("inputTensor", "outputTensor"); 115 } 116 }; 117 118 struct DepthwiseConvolution2dSameFixture : DepthwiseConvolution2dFixture 119 { DepthwiseConvolution2dSameFixtureDepthwiseConvolution2dSameFixture120 DepthwiseConvolution2dSameFixture() 121 : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape 122 "[ 1, 3, 3, 1 ]", // outputShape 123 "[ 1, 3, 3, 1 ]", // filterShape 124 "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData 125 "1", // stride w and h 126 "SAME") // padding type 127 {} 128 }; 129 130 TEST_CASE_FIXTURE(DepthwiseConvolution2dSameFixture, "ParseDepthwiseConv2DSame") 131 { 132 RunTest<4, armnn::DataType::QAsymmU8>( 133 0, 134 { 0, 1, 2, 135 3, 4, 5, 136 6, 7, 8 }, 137 // the expected values were generated using the example python implementation at 138 // https://eli.thegreenplace.net/2018/depthwise-separable-convolutions-for-machine-learning/ 139 // divide the expected values by the output scale, as it is not 1.0 140 { 14/2, 35/2, 38/2, 141 57/2, 120/2, 111/2, 142 110/2, 197/2, 158/2 }); 143 } 144 145 struct DepthwiseConvolution2dValidFixture : DepthwiseConvolution2dFixture 146 { DepthwiseConvolution2dValidFixtureDepthwiseConvolution2dValidFixture147 DepthwiseConvolution2dValidFixture () 148 : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape 149 "[ 1, 1, 1, 1 ]", // outputShape 150 "[ 1, 3, 3, 1 ]", // filterShape 151 "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData 152 "1", // stride w and h 153 "VALID") // padding type 154 {} 155 }; 156 157 TEST_CASE_FIXTURE(DepthwiseConvolution2dValidFixture, "ParseDepthwiseConv2DValid") 158 { 159 RunTest<4, armnn::DataType::QAsymmU8>( 160 0, 161 { 0, 1, 2, 162 3, 4, 5, 163 6, 7, 8 }, 164 // divide the expected values by the output scale, as it is not 1.0 165 { 120/2 }); 166 } 167 168 struct DepthwiseConvolution2dSameBiasFixture : DepthwiseConvolution2dFixture 169 { DepthwiseConvolution2dSameBiasFixtureDepthwiseConvolution2dSameBiasFixture170 DepthwiseConvolution2dSameBiasFixture() 171 : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape 172 "[ 1, 3, 3, 1 ]", // outputShape 173 "[ 1, 3, 3, 1 ]", // filterShape 174 "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData 175 "1", // stride w and h 176 "SAME", // padding type 177 "[ 1 ]", // biasShape 178 "[ 10, 0, 0, 0 ]") // biasData 179 {} 180 }; 181 182 TEST_CASE_FIXTURE(DepthwiseConvolution2dSameBiasFixture, "ParseDepthwiseConv2DSameBias") 183 { 184 RunTest<4, armnn::DataType::QAsymmU8>( 185 0, 186 { 0, 1, 2, 187 3, 4, 5, 188 6, 7, 8 }, 189 // divide the expected values by the output scale, as it is not 1.0 190 { ( 14+10)/2, ( 35+10)/2, ( 38+10)/2, 191 ( 57+10)/2, (120+10)/2, (111+10)/2, 192 (110+10)/2, (197+10)/2, (158+10)/2 }); 193 } 194 195 struct DynamicDepthwiseConvolution2dSameBiasFixture : DepthwiseConvolution2dFixture 196 { DynamicDepthwiseConvolution2dSameBiasFixtureDynamicDepthwiseConvolution2dSameBiasFixture197 DynamicDepthwiseConvolution2dSameBiasFixture() 198 : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape 199 "[ ]", // outputShape 200 "[ 1, 3, 3, 1 ]", // filterShape 201 "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData 202 "1", // stride w and h 203 "SAME", // padding type 204 "[ 1 ]", // biasShape 205 "[ 10, 0, 0, 0 ]") // biasData 206 {} 207 }; 208 209 TEST_CASE_FIXTURE(DynamicDepthwiseConvolution2dSameBiasFixture, "ParseDynamicDepthwiseConv2DSameBias") 210 { 211 RunTest<4, armnn::DataType::QAsymmU8, armnn::DataType::QAsymmU8>(0, 212 { { "inputTensor", { 0, 1, 2, 213 3, 4, 5, 214 6, 7, 8 } } }, 215 { { "outputTensor", { ( 14+10)/2, ( 35+10)/2, ( 38+10)/2, 216 ( 57+10)/2, (120+10)/2, (111+10)/2, 217 (110+10)/2, (197+10)/2, (158+10)/2 } } }, 218 true); 219 } 220 221 struct DepthwiseConvolution2dFixture2 : public ParserFlatbuffersFixture 222 { DepthwiseConvolution2dFixture2DepthwiseConvolution2dFixture2223 explicit DepthwiseConvolution2dFixture2(const std::string& inputShape, 224 const std::string& outputShape, 225 const std::string& filterShape, 226 const std::string& filterData, 227 const std::string& strides, 228 const std::string& paddingType, 229 const std::string biasShape = "", 230 const std::string biasData = "", 231 const std::string filter_quant_min = "[ 0.0 ]", 232 const std::string filter_quant_max = "[ 255.0 ]", 233 const std::string filter_quant_scale = "[ 1.0 ]", 234 const std::string filter_quant_zero_point = "[ 0 ]", 235 const std::string filter_quant_axis = "", 236 const std::string output_scale = "[ 1.0 ]") 237 { 238 std::string inputTensors = "[ 0, 2 ]"; 239 std::string biasTensor = ""; 240 std::string biasBuffer = ""; 241 if (biasShape.size() > 0 && biasData.size() > 0) 242 { 243 inputTensors = "[ 0, 2, 3 ]"; 244 biasTensor = R"( 245 { 246 "shape": )" + biasShape + R"( , 247 "type": "INT32", 248 "buffer": 3, 249 "name": "biasTensor", 250 "quantization": { 251 "min": [ 0.0 ], 252 "max": [ 255.0 ], 253 "scale": [ 1.0 ], 254 "zero_point": [ 0 ], 255 } 256 } )"; 257 biasBuffer = R"( 258 { "data": )" + biasData + R"(, }, )"; 259 } 260 261 std::string filter_qantization = 262 R"( 263 "min": )" + filter_quant_min + R"(, 264 "max": )" + filter_quant_max + R"(, 265 "scale": )" + filter_quant_scale + R"(, 266 "zero_point": )" + filter_quant_zero_point; 267 // A given quantization axis indicates if per channel quantization is used for filters 268 if (filter_quant_axis.size() > 0) 269 { 270 filter_qantization += 271 R"(, 272 "quantized_dimension": )" + filter_quant_axis; 273 } 274 m_JsonString = R"( 275 { 276 "version": 3, 277 "operator_codes": [ { "builtin_code": "DEPTHWISE_CONV_2D" } ], 278 "subgraphs": [ { 279 "tensors": [ 280 { 281 "shape": )" + inputShape + R"(, 282 "type": "INT8", 283 "buffer": 0, 284 "name": "inputTensor", 285 "quantization": { 286 "min": [ 0.0 ], 287 "max": [ 255.0 ], 288 "scale": [ 1.0 ], 289 "zero_point": [ 0 ], 290 } 291 }, 292 { 293 "shape": )" + outputShape + R"(, 294 "type": "INT8", 295 "buffer": 1, 296 "name": "outputTensor", 297 "quantization": { 298 "min": [ 0.0 ], 299 "max": [ 511.0 ], 300 "scale": )" + output_scale + R"(, 301 "zero_point": [ 0 ], 302 } 303 }, 304 { 305 "shape": )" + filterShape + R"(, 306 "type": "INT8", 307 "buffer": 2, 308 "name": "filterTensor", 309 "quantization": {)" + filter_qantization + R"( 310 } 311 }, )" + biasTensor + R"( 312 ], 313 "inputs": [ 0 ], 314 "outputs": [ 1 ], 315 "operators": [ 316 { 317 "opcode_index": 0, 318 "inputs": )" + inputTensors + R"(, 319 "outputs": [ 1 ], 320 "builtin_options_type": "DepthwiseConv2DOptions", 321 "builtin_options": { 322 "padding": ")" + paddingType + R"(", 323 "stride_w": )" + strides+ R"(, 324 "stride_h": )" + strides+ R"(, 325 "depth_multiplier": 1, 326 "fused_activation_function": "NONE" 327 }, 328 "custom_options_format": "FLEXBUFFERS" 329 } 330 ], 331 } ], 332 "buffers" : [ 333 { }, 334 { }, 335 { "data": )" + filterData + R"(, }, )" 336 + biasBuffer + R"( 337 ] 338 } 339 )"; 340 SetupSingleInputSingleOutput("inputTensor", "outputTensor"); 341 } 342 }; 343 344 345 // No quantization meaning scale=1.0 and offset=0.0 and tensor quantization 346 struct DepthwiseConvolution2dNoQuantFixture : DepthwiseConvolution2dFixture2 347 { DepthwiseConvolution2dNoQuantFixtureDepthwiseConvolution2dNoQuantFixture348 DepthwiseConvolution2dNoQuantFixture() 349 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 350 "[ 1, 3, 3, 3 ]", // outputShape 351 "[ 1, 3, 3, 3 ]", // filterShape 352 "[ 9,8,7, 6,5,4, 3,2,1, " 353 "9,8,7, 6,5,4, 3,2,1, " 354 "9,8,7, 6,5,4, 3,2,1 ]", // filterData 355 "1", // stride w and h 356 "SAME", // padding type 357 "", // bias shape 358 "" // bias data 359 ) 360 {} 361 }; 362 363 // No quantization meaning scale=1.0 and offset=0.0 and tensor quantization 364 TEST_CASE_FIXTURE(DepthwiseConvolution2dNoQuantFixture, "ParseDepthwiseConv2DNoQuant") 365 { 366 RunTest<4, armnn::DataType::QAsymmS8>( 367 0, 368 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 369 { 18, 14, 10, 36, 30, 24, 30, 26, 22, 27, 21, 15, 54, 45, 370 36, 45, 39, 33, 18, 14, 10, 36, 30, 24, 30, 26, 22}); 371 } 372 373 // Uses per channel quantization on weights but with scales = 1.0 and offsets = 0.0 374 struct DepthwiseConvolution2dNoChannelQuantFixture : DepthwiseConvolution2dFixture2 375 { DepthwiseConvolution2dNoChannelQuantFixtureDepthwiseConvolution2dNoChannelQuantFixture376 DepthwiseConvolution2dNoChannelQuantFixture() 377 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 378 "[ 1, 3, 3, 3 ]", // outputShape 379 "[ 1, 3, 3, 3 ]", // filterShape 380 "[ 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1 ]", //filterData 381 "1", // stride w and h 382 "SAME", // padding type 383 "", // bias shape 384 "", // bias data 385 "[ 0.0 ]", // filter quantization min values 386 "[ 255.0 ]", // filter quantization max values 387 "[ 1.0, 1.0, 1.0]", // filter quantization scales 388 "[ 0, 0, 0]", // filter quantization zero-points 389 "3" // filter quantized axis 390 // (in case of per channel quantization) 391 ) 392 {} 393 }; 394 395 // Uses per channel quantization on weights but with scales = 1.0 and offsets = 0.0 396 TEST_CASE_FIXTURE(DepthwiseConvolution2dNoChannelQuantFixture, "ParseDepthwiseConv2DFilterNoChannelQuant") 397 { 398 RunTest<4, armnn::DataType::QAsymmS8>( 399 0, 400 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 401 { 18, 14, 10, 36, 30, 24, 30, 26, 22, 27, 21, 15, 54, 45, 402 36, 45, 39, 33, 18, 14, 10, 36, 30, 24, 30, 26, 22}); 403 } 404 405 // Uses per channel quantization on weights but all scales are set to the same value 406 struct DepthwiseConvolution2dWeightsPerChannelQuantFixture : DepthwiseConvolution2dFixture2 407 { DepthwiseConvolution2dWeightsPerChannelQuantFixtureDepthwiseConvolution2dWeightsPerChannelQuantFixture408 DepthwiseConvolution2dWeightsPerChannelQuantFixture() 409 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 410 "[ 1, 3, 3, 3 ]", // outputShape 411 "[ 1, 3, 3, 3 ]", // filterShape 412 // filterData is [ 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1 ] 413 // quantized per channel with q_dim=3 414 "[36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, " 415 "20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 8, 4]", 416 "1", // stride w and h 417 "SAME", // padding type 418 "", // bias shape 419 "", // bias data 420 "[ 0.0 ]", // filter quantization min values 421 "[ 255.0 ]", // filter quantization max values 422 "[ 0.25, 0.25, 0.25]", // filter quantization scales 423 "[ 0, 0, 0]", // filter quantization zero-points 424 "3" // filter quantized axis 425 // (in case of per channel quantization) 426 ) 427 {} 428 }; 429 430 // Weights are per channel quantized but all scales are set to the same value 431 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuantFixture, 432 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant") 433 { 434 RunTest<4, armnn::DataType::QAsymmS8>( 435 0, 436 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 437 { 18, 14, 10, 36, 30, 24, 30, 26, 22, 27, 21, 15, 54, 45, 438 36, 45, 39, 33, 18, 14, 10, 36, 30, 24, 30, 26, 22}); 439 } 440 441 // Uses per channel quantization on weights all scales are different in this test 442 struct DepthwiseConvolution2dWeightsPerChannelQuant1Fixture : DepthwiseConvolution2dFixture2 443 { DepthwiseConvolution2dWeightsPerChannelQuant1FixtureDepthwiseConvolution2dWeightsPerChannelQuant1Fixture444 DepthwiseConvolution2dWeightsPerChannelQuant1Fixture() 445 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 446 "[ 1, 3, 3, 3 ]", // outputShape 447 "[ 1, 3, 3, 3 ]", // filterShape 448 // filterData is [ 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1, 9,8,7, 6,5,4, 3,2,1 ] 449 // quantized per channel with q_dim=3 450 "[36, 40, 70, 24, 25, 40, 12, 10, 10, 36, 40, 70, 24, " 451 "25, 40, 12, 10, 10, 36, 40, 70, 24, 25, 40, 12, 10, 10]", 452 "1", // stride w and h 453 "SAME", // padding type 454 "", // bias shape 455 "", // bias data 456 "[ 0.0 ]", // filter quantization min values 457 "[ 255.0 ]", // filter quantization max values 458 "[ 0.25, 0.2, 0.1]", // filter quantization scales 459 "[ 0, 0, 0]", // filter quantization zero-points 460 "3" // filter quantized axis 461 // (in case of per channel quantization) 462 ) 463 {} 464 }; 465 466 // Uses per channel quantization on weights all scales are different in this test 467 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant1Fixture, 468 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant1") 469 { 470 RunTest<4, armnn::DataType::QAsymmS8>( 471 0, 472 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 473 { 18, 14, 10, 36, 30, 24, 30, 26, 22, 27, 21, 15, 54, 45, 474 36, 45, 39, 33, 18, 14, 10, 36, 30, 24, 30, 26, 22}); 475 } 476 477 478 // Uses per channel quantization on weights all scales are different in this test 479 // Uses different shape for weights and input compared to the other tests above 480 struct DepthwiseConvolution2dWeightsPerChannelQuant2Fixture : DepthwiseConvolution2dFixture2 481 { DepthwiseConvolution2dWeightsPerChannelQuant2FixtureDepthwiseConvolution2dWeightsPerChannelQuant2Fixture482 DepthwiseConvolution2dWeightsPerChannelQuant2Fixture() 483 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 484 "[ 1, 4, 4, 4 ]", // outputShape 485 "[ 1, 2, 2, 4 ]", // filterShape 486 // filterData is [ 9,8,7,6, 5,4,3,2, 1,9,8,7, 6,5,4,3 ] 487 // quantized per channel with q_dim=3 488 "[36, 40, 70, 20, 20, 20, 30, 6, 4, 45, 80, 23, 24, 25, 40, 10]", 489 "1", // stride w and h 490 "SAME", // padding type 491 "", // bias shape 492 "", // bias data 493 "[ 0.0 ]", // filter quantization min values 494 "[ 255.0 ]", // filter quantization max values 495 "[ 0.25, 0.2, 0.1, 0.3]", // filter quantization scales 496 "[ 0, 0, 0, 0]", // filter quantization zero-points 497 "3" // filter quantized axis 498 // (in case of per channel quantization) 499 ) 500 {} 501 }; 502 503 // Uses per channel quantization on weights all scales are different in this test 504 // Uses different shape for weights and input compared to the other tests above 505 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant2Fixture, 506 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant2") 507 { 508 RunTest<4, armnn::DataType::QAsymmS8>( 509 0, 510 { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 511 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 512 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 513 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}, 514 { 21, 26, 22, 18, 21, 26, 22, 18, 21, 26, 22, 18, 10, 17, 15, 13, 515 21, 26, 22, 18, 21, 26, 22, 18, 21, 26, 22, 18, 10, 17, 15, 13, 516 21, 26, 22, 18, 21, 26, 22, 18, 21, 26, 22, 18, 10, 17, 15, 13, 517 14, 12, 10, 8, 14, 12, 10, 8, 14, 12, 10, 8, 9, 8, 7, 6}); 518 } 519 520 // Test for depthwise_multiplier different to one (M > 1) 521 struct DepthwiseConvolution2dWeightsPerChannelQuant4Fixture : DepthwiseConvolution2dFixture2 522 { DepthwiseConvolution2dWeightsPerChannelQuant4FixtureDepthwiseConvolution2dWeightsPerChannelQuant4Fixture523 DepthwiseConvolution2dWeightsPerChannelQuant4Fixture() 524 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 525 "[ 1, 4, 4, 16 ]", // outputShape 526 "[ 1, 2, 2, 16 ]", // filterShape 527 // filter data is [ 9,8,7,6, 5,4,3,2, 1,9,8,7, 6,5,4,3, 528 // 9,8,7,6, 5,4,3,2, 1,9,8,7, 6,5,4,3, 529 // 9,8,7,6, 5,4,3,2, 1,9,8,7, 6,5,4,3, 530 // 9,8,7,6, 5,4,3,2, 1,9,8,7, 6,5,4,3 ] 531 // quantized per channel with q_dim=3 532 "[36, 40, 70, 20, 20, 20, 30, 6, 4, 45, 80, 23, 24, 25, 40, 10, " 533 "36, 40, 70, 20, 20, 20, 30, 6, 4, 45, 80, 23, 24, 25, 40, 10, " 534 "36, 40, 70, 20, 20, 20, 30, 6, 4, 45, 80, 23, 24, 25, 40, 10, " 535 "36, 40, 70, 20, 20, 20, 30, 6, 4, 45, 80, 23, 24, 25, 40, 10]", 536 "1", // stride w and h 537 "SAME", // padding type 538 "", // bias shape 539 "", // bias data 540 "[ 0.0 ]", // filter quantization min values 541 "[ 255.0 ]", // filter quantization max values 542 "[ 0.25, 0.2, 0.1, 0.3," 543 "0.25, 0.2, 0.1, 0.3," 544 "0.25, 0.2, 0.1, 0.3," 545 "0.25, 0.2, 0.1, 0.3]", // filter quantization scales 546 "[ 0, 0, 0, 0]", // filter quantization zero-points 547 "3" // filter quantized axis 548 // (in case of per channel quantization) 549 ) 550 {} 551 }; 552 553 // Test for depthwise_multiplier different to one (M > 1) 554 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4Fixture, 555 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4") 556 { 557 RunTest<4, armnn::DataType::QAsymmS8>( 558 0, 559 { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 560 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 561 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 562 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}, 563 { 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 564 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 565 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 566 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 567 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 568 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 569 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 570 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 571 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 572 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 573 36, 32, 28, 24, 20, 16, 12, 8, 4, 36, 32, 28, 24, 20, 16, 12, 574 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 575 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 576 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 577 18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 16, 14, 12, 10, 8, 6, 578 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 8, 7, 6, 5, 4, 3}); 579 } 580 581 582 struct DepthwiseConvolution2dWeightsPerChannelQuant6Fixture : DepthwiseConvolution2dFixture2 583 { DepthwiseConvolution2dWeightsPerChannelQuant6FixtureDepthwiseConvolution2dWeightsPerChannelQuant6Fixture584 DepthwiseConvolution2dWeightsPerChannelQuant6Fixture() 585 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 586 "[ 1, 4, 4, 16 ]", // outputShape 587 "[ 1, 2, 2, 16 ]", // filterShape 588 // filter data is [ 3,4,1,1,1,3,3,2,1,4,3,4,1,2,2,4, 589 // 2,0,3,1,0,2,4,3,4,3,0,1,3,4,4,1, 590 // 3,3,2,0,0,0,1,3,3,2,4,4,3,1,1,3, 591 // 1,0,0,2,3,0,1,1,4,2,2,1,2,3,2,0] 592 // quantized per channel with q_dim=3 593 "[12,20,10, 3, 4,15,30, 6, 4,20,30,12, 4,10,20,12," 594 " 8, 0,30, 3, 0,10,40, 9,16,15, 0, 3,12,20,40, 3," 595 " 12,15,20, 0, 0, 0,10, 9,12,10,40,12,12, 5,10, 9," 596 " 4, 0, 0, 6,12, 0,10, 3,16,10,20, 3, 8,15,20, 0]", 597 "1", // stride w and h 598 "SAME", // padding type 599 "", // bias shape 600 "", // bias data 601 "[ 0.0 ]", // filter quantization min values 602 "[ 255.0 ]", // filter quantization max values 603 "[ 0.25, 0.2, 0.1, 0.333333333," 604 "0.25, 0.2, 0.1, 0.333333333," 605 "0.25, 0.2, 0.1, 0.333333333," 606 "0.25, 0.2, 0.1, 0.333333333]", // filter quantization scales 607 "[ 0, 0, 0, 0]", // filter quantization zero-points 608 "3" // filter quantized axis 609 // (in case of per channel quantization) 610 ) 611 {} 612 }; 613 614 615 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant6Fixture, 616 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant6") 617 { 618 RunTest<4, armnn::DataType::QAsymmS8>( 619 0, 620 { 1,0,1,2,0,4,4,0,2,1,2,0,1,3,3,0, 621 1,2,2,3,3,4,1,1,2,4,1,3,4,2,0,2, 622 0,3,1,3,4,3,2,0,1,2,3,3,0,2,4,2, 623 1,2,1,4,3,4,1,3,1,0,2,3,1,3,2,0}, 624 { 9, 7, 3, 7,12, 8,22,22,27,22,13,17,13,10, 9,17, 625 15, 9,12, 6,16,14,24,27,19,26,18,23, 9,10, 7, 3, 626 18,14, 9,11, 7, 9,21,25,17,19,10,15,13, 9, 7, 9, 627 15,16, 9, 1, 3, 9,11,12, 3,12, 9,12, 6, 2, 2, 6, 628 13, 4,10,12,11,14,28,28,17,17,14,15,15,13,13,22, 629 26,24,17, 7,10,20,33,31,23,17,17,16,16,23,20, 7, 630 17,11,16, 6,10,16,24,22,26,18,23,20,22,23,21,23, 631 12,16, 4, 4, 2, 6, 8,10,12, 8,16,16, 8, 6, 6,14, 632 14, 3,14,10,15,15,27,25,16,14, 9,11,21,19,16,24, 633 24,25,13, 7, 3,13,21,24,25,23,14,17,24,24,21,12, 634 7, 7, 3, 3,11,10,17,13,33,32,21,26,18,17,17,23, 635 3, 3, 2, 0, 2, 6, 9,13,10,20,20,24, 2, 4, 4, 8, 636 9, 4,10, 4, 2,14,22,16, 5, 7, 3, 5,13,20,20,19, 637 11,12, 6, 4, 4,12,12, 8, 9,10, 3, 6,12,18,18,15, 638 5, 4, 4, 2, 0, 6,12, 9,10,14, 6,10, 3, 6, 6,12, 639 3, 4, 1, 1, 3, 9, 9, 6, 2, 8, 6, 8, 0, 0, 0, 0}); 640 } 641 642 643 struct DepthwiseConvolution2dWeightsPerChannelQuant1_1Fixture : DepthwiseConvolution2dFixture2 644 { DepthwiseConvolution2dWeightsPerChannelQuant1_1FixtureDepthwiseConvolution2dWeightsPerChannelQuant1_1Fixture645 DepthwiseConvolution2dWeightsPerChannelQuant1_1Fixture() 646 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 647 "[ 1, 3, 3, 3 ]", // outputShape 648 "[ 1, 3, 3, 3 ]", // filterShape 649 // filterData is [ 1,4,0,2,4,3,1,0,1, 650 // 3,0,4,0,1,3,4,2,4, 651 // 3,0,3,4,4,0,3,4,2] 652 // quantized per channel with q_dim=3 653 "[ 4,20, 0, 8,20,30, 4, 0,10,12," 654 " 0,40, 0, 5,30,16,10,40,12, 0," 655 "30,16,20, 0,12,20,20]", 656 "1", // stride w and h 657 "SAME", // padding type 658 "", // bias shape 659 "", // bias data 660 "[ 0.0 ]", // filter quantization min values 661 "[ 255.0 ]", // filter quantization max values 662 "[ 0.25, 0.2, 0.1]", // filter quantization scales 663 "[ 0, 0, 0]", // filter quantization zero-points 664 "3" // filter quantized axis 665 // (in case of per channel quantization) 666 ) 667 {} 668 }; 669 670 671 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant1_1Fixture, 672 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant1_1") 673 { 674 RunTest<4, armnn::DataType::QAsymmS8>( 675 0, 676 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 677 { 11,11, 9,17,11,16,10, 5,10, 678 14,15,13,21,19,20,13,13,13, 679 7, 7,11,11,11,15, 6, 9,10}); 680 } 681 682 // Same with input different to 1 683 struct DepthwiseConvolution2dWeightsPerChannelQuant1_2Fixture : DepthwiseConvolution2dFixture2 684 { DepthwiseConvolution2dWeightsPerChannelQuant1_2FixtureDepthwiseConvolution2dWeightsPerChannelQuant1_2Fixture685 DepthwiseConvolution2dWeightsPerChannelQuant1_2Fixture() 686 : DepthwiseConvolution2dFixture2("[ 1, 3, 3, 3 ]", // inputShape 687 "[ 1, 3, 3, 3 ]", // outputShape 688 "[ 1, 3, 3, 3 ]", // filterShape 689 // filterData is [ 1,4,0,2,4,3,1,0,1, 690 // 3,0,4,0,1,3,4,2,4, 691 // 3,0,3,4,4,0,3,4,2] 692 // quantized per channel with q_dim=3 693 "[ 4,20, 0, 8,20,30, 4, 0,10,12," 694 " 0,40, 0, 5,30,16,10,40,12, 0," 695 "30,16,20, 0,12,20,20]", 696 "1", // stride w and h 697 "SAME", // padding type 698 "", // bias shape 699 "", // bias data 700 "[ 0.0 ]", // filter quantization min values 701 "[ 255.0 ]", // filter quantization max values 702 "[ 0.25, 0.2, 0.1]", // filter quantization scales 703 "[ 0, 0, 0]", // filter quantization zero-points 704 "3" // filter quantized axis 705 // (in case of per channel quantization) 706 ) 707 {} 708 }; 709 710 711 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant1_2Fixture, 712 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant1_2") 713 { 714 RunTest<4, armnn::DataType::QAsymmS8>( 715 0, 716 { 3,2,0,0,4,3,0,1,2, 717 0,1,3,0,4,2,2,2,3, 718 2,4,3,2,0,4,3,4,0}, 719 { 0,30,16,15,30,32, 8, 9,24, 720 20,33,28,34,48,50,18,38,35, 721 8, 8,36,20,28,33,10,28,25}); 722 } 723 724 725 struct DepthwiseConvolution2dWeightsPerChannelQuant4_1Fixture : DepthwiseConvolution2dFixture2 726 { DepthwiseConvolution2dWeightsPerChannelQuant4_1FixtureDepthwiseConvolution2dWeightsPerChannelQuant4_1Fixture727 DepthwiseConvolution2dWeightsPerChannelQuant4_1Fixture() 728 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 729 "[ 1, 4, 4, 16 ]", // outputShape 730 "[ 1, 2, 2, 16 ]", // filterShape 731 // filter data is [ 3,4,1,1,1,3,3,2,1,4,3,4,1,2,2,4, 732 // 2,0,3,1,0,2,4,3,4,3,0,1,3,4,4,1, 733 // 3,3,2,0,0,0,1,3,3,2,4,4,3,1,1,3, 734 // 1,0,0,2,3,0,1,1,4,2,2,1,2,3,2,0 ] 735 // quantized per channel with q_dim=3 736 "[12,20,10, 3, 4,15,30, 6, 4,20,30,13, 4,10,20,13," 737 " 8, 0,30, 3, 0,10,40,10,16,15, 0, 3,12,20,40, 3," 738 " 12,15,20, 0, 0, 0,10,10,12,10,40,13,12, 5,10,10," 739 " 4, 0, 0, 6,12, 0,10, 3,16,10,20, 3, 8,15,20, 0]", 740 "1", // stride w and h 741 "SAME", // padding type 742 "", // bias shape 743 "", // bias data 744 "[ 0.0 ]", // filter quantization min values 745 "[ 255.0 ]", // filter quantization max values 746 "[ 0.25, 0.2, 0.1, 0.3," 747 "0.25, 0.2, 0.1, 0.3," 748 "0.25, 0.2, 0.1, 0.3," 749 "0.25, 0.2, 0.1, 0.3]", // filter quantization scales 750 "[ 0, 0, 0, 0]", // filter quantization zero-points 751 "3" // filter quantized axis 752 // (in case of per channel quantization) 753 ) 754 {} 755 }; 756 757 758 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4_1Fixture, 759 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4_1") 760 { 761 RunTest<4, armnn::DataType::QAsymmS8>( 762 0, 763 { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 764 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 765 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 766 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}, 767 { 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 768 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 769 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 770 6, 7, 3, 1, 1, 3, 4, 5, 4, 6, 7, 8, 4, 3, 3, 7, 771 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 772 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 773 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 774 6, 7, 3, 1, 1, 3, 4, 5, 4, 6, 7, 8, 4, 3, 3, 7, 775 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 776 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 777 9, 7, 6, 4, 4, 5, 9, 9,12,11, 9,10, 9,10, 9, 8, 778 6, 7, 3, 1, 1, 3, 4, 5, 4, 6, 7, 8, 4, 3, 3, 7, 779 5, 4, 4, 2, 1, 5, 7, 5, 5, 7, 3, 5, 4, 6, 6, 5, 780 5, 4, 4, 2, 1, 5, 7, 5, 5, 7, 3, 5, 4, 6, 6, 5, 781 5, 4, 4, 2, 1, 5, 7, 5, 5, 7, 3, 5, 4, 6, 6, 5, 782 3, 4, 1, 1, 1, 3, 3, 2, 1, 4, 3, 4, 1, 2, 2, 4}); 783 } 784 785 786 787 struct DepthwiseConvolution2dWeightsPerChannelQuant4_2Fixture : DepthwiseConvolution2dFixture2 788 { DepthwiseConvolution2dWeightsPerChannelQuant4_2FixtureDepthwiseConvolution2dWeightsPerChannelQuant4_2Fixture789 DepthwiseConvolution2dWeightsPerChannelQuant4_2Fixture() 790 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 791 "[ 1, 4, 4, 16 ]", // outputShape 792 "[ 1, 2, 2, 16 ]", // filterShape 793 // filter data is [ 3,4,1,1,1,3,3,2,1,4,3,4,1,2,2,4, 794 // 2,0,3,1,0,2,4,3,4,3,0,1,3,4,4,1, 795 // 3,3,2,0,0,0,1,3,3,2,4,4,3,1,1,3, 796 // 1,0,0,2,3,0,1,1,4,2,2,1,2,3,2,0 ] 797 // quantized per channel with q_dim=3 798 "[12,20,10, 3, 4,15,30, 6, 4,20,30,13, 4,10,20,13," 799 " 8, 0,30, 3, 0,10,40,10,16,15, 0, 3,12,20,40, 3," 800 " 12,15,20, 0, 0, 0,10,10,12,10,40,13,12, 5,10,10," 801 " 4, 0, 0, 6,12, 0,10, 3,16,10,20, 3, 8,15,20, 0]", 802 "1", // stride w and h 803 "SAME", // padding type 804 "", // bias shape 805 "", // bias data 806 "[ 0.0 ]", // filter quantization min values 807 "[ 255.0 ]", // filter quantization max values 808 "[ 0.25, 0.2, 0.1, 0.3," 809 "0.25, 0.2, 0.1, 0.3," 810 "0.25, 0.2, 0.1, 0.3," 811 "0.25, 0.2, 0.1, 0.3]", // filter quantization scales 812 "[ 0, 0, 0, 0]", // filter quantization zero-points 813 "3" // filter quantized axis 814 // (in case of per channel quantization) 815 ) 816 {} 817 }; 818 819 820 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4_2Fixture, 821 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4_2") 822 { 823 RunTest<4, armnn::DataType::QAsymmS8>( 824 0, 825 { 3,3,3,4, 4,4,0,0, 0,3,4,3, 0,2,2,3, 826 3,0,3,0, 0,3,2,1, 4,1,2,2, 0,0,0,4, 827 3,2,2,2, 2,1,0,4, 4,3,2,4, 3,2,0,0, 828 4,1,4,4, 1,0,4,3, 3,2,0,3, 1,1,0,2}, 829 { 26,21,21, 7,12,17,28,21,20,22,25,26, 6,11,10,16, 830 16,16, 4,12, 7,18,28,27,30,20,12,14,16,19,17, 6, 831 12,12, 8, 0, 3,13,18,15,18,26,20,26,26,32,28,21, 832 0, 0, 0, 0, 2, 6, 6, 4, 2, 8, 6, 8,15,10,10,24, 833 20,21, 9, 7, 3, 6,15,16,17,22,17,22,17,18,14, 7, 834 18, 6,16,12,12,11,17,15,18,18,10,12,27,26,22,18, 835 27,28,12,10, 7, 3, 8,13, 8,12,14,16,26,24,24,24, 836 9, 9, 6, 0, 0, 0, 2, 6, 0, 0, 0, 0, 4, 8, 8,16, 837 26,24,17, 7, 2, 8,11,10,30,24,30,28,32,33,30,24, 838 20,11,16,12, 7, 9,17,13,20,14,16,18,31,36,33,29, 839 28,25,19, 9, 6,13,20,19, 2, 8, 6, 8,17,17,15,25, 840 12,15, 5, 3, 2, 6, 7, 7, 0, 0, 0, 0, 6, 2, 2, 6, 841 14,16, 7, 5, 1, 3, 3, 2,20,28,12,20,13,20,20,19, 842 9, 4,10, 4, 0, 4, 8, 6, 4,16,12,16,12,18,18,15, 843 11,12, 6, 4, 2, 8,10, 7, 0, 0, 0, 0, 9,14,14,14, 844 3, 4, 1, 1, 1, 3, 3, 2, 0, 0, 0, 0, 2, 4, 4, 8}); 845 } 846 847 848 struct DepthwiseConvolution2dWeightsPerChannelQuant4_5Fixture : DepthwiseConvolution2dFixture2 849 { DepthwiseConvolution2dWeightsPerChannelQuant4_5FixtureDepthwiseConvolution2dWeightsPerChannelQuant4_5Fixture850 DepthwiseConvolution2dWeightsPerChannelQuant4_5Fixture() 851 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 852 "[ 1, 4, 4, 16 ]", // outputShape 853 "[ 1, 2, 2, 16 ]", // filterShape 854 // filter data is [ 1, 4, 9, 16, 25, 36, 855 // 49, 64, 81, 100, 121, 144, 856 // 169, 196, 225, 256, 17, 36, 857 // 57, 80, 105, 132, 161, 192, 858 // 225, 260, 297, 336, 377, 420, 859 // 465, 512, 33, 68, 105, 144, 860 // 185, 228, 273, 320, 369, 420, 861 // 473, 528, 585, 644, 705, 768, 862 // 49, 100, 153, 208, 265, 324, 863 // 385, 448, 513, 580, 649, 720, 864 // 793, 868, 945,1024 ] 865 // quantized per channel with q_dim=3 866 "[ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16," 867 " 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32," 868 " 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48," 869 "49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64]", 870 "1", // stride w and h 871 "SAME", // padding type 872 "", // bias shape 873 "", // bias data 874 "[ 0.0 ]", // filter quantization min values 875 "[ 255.0 ]", // filter quantization max values 876 "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16]", // filter quantization scales 877 "[ 0, 0, 0, 0]", // filter quantization zero-points 878 "3", // filter quantized axis 879 // (in case of per channel quantization) 880 "[ 100.0 ]" // output scale 881 ) 882 {} 883 }; 884 885 // Test for depthwise_multiplier different to one (M > 1) 886 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4_5Fixture, 887 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4_5") 888 { 889 RunTest<4, armnn::DataType::QAsymmS8>( 890 0, 891 { 1,1,1,2,2,2,1,2,1,2,2,1,2,2,1,1,1,1,1,1,1,2,2,2, 892 1,2,2,2,1,1,1,2,1,1,1,1,2,1,2,1,2,1,1,2,1,2,1,1, 893 1,2,2,1,2,2,1,1,2,1,2,1,1,2,1,2}, 894 { 1, 2, 3, 5, 9,11,14,16,17,19,21,24,32,36,39,43, 895 1, 2, 3, 4,11,14,17,20,22,26,29,33,34,38,42,46, 896 1, 2, 3, 5, 8,11,13,16,16,18,21,24,33,36,39,43, 897 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6,13,14,16,17, 898 1, 3, 4, 6, 6, 8,10,12,19,22,24,27,23,25,28,30, 899 1, 3, 5, 8, 7, 8,10,12,18,21,24,27,32,36,39,43, 900 1, 2, 4, 5, 8,10,13,15,12,14,16,18,30,33,37,40, 901 0, 0, 1, 1, 3, 4, 5, 7, 4, 5, 5, 6, 9,10,11,12, 902 1, 3, 5, 7,10,12,15,17,17,20,23,25,19,21,23,25, 903 2, 4, 6, 8, 7, 9,11,13,17,20,23,25,23,25,28,30, 904 1, 2, 4, 6, 9,11,14,16,15,17,20,22,28,31,35,38, 905 0, 0, 1, 1, 4, 5, 6, 7, 4, 5, 5, 6,13,14,16,17, 906 0, 0, 1, 1, 2, 3, 4, 5, 3, 4, 5, 6, 5, 6, 6, 7, 907 0, 0, 1, 1, 1, 2, 2, 3, 5, 6, 7, 8, 5, 6, 6, 7, 908 0, 0, 0, 1, 2, 3, 3, 4, 3, 4, 5, 6, 9,10,11,12, 909 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 3, 3, 4, 5}); 910 } 911 912 913 struct DepthwiseConvolution2dWeightsPerChannelQuant4_3_1Fixture : DepthwiseConvolution2dFixture2 914 { DepthwiseConvolution2dWeightsPerChannelQuant4_3_1FixtureDepthwiseConvolution2dWeightsPerChannelQuant4_3_1Fixture915 DepthwiseConvolution2dWeightsPerChannelQuant4_3_1Fixture() 916 : DepthwiseConvolution2dFixture2("[ 1, 4, 4, 4 ]", // inputShape 917 "[ 1, 4, 4, 16 ]", // outputShape 918 "[ 1, 2, 2, 16 ]", // filterShape 919 // filter data is [ 3,4,1,1,1,3,3,2,1,4,3,4,1,2,2,4, 920 // 2,0,3,1,0,2,4,3,4,3,0,1,3,4,4,1, 921 // 3,3,2,0,0,0,1,3,3,2,4,4,3,1,1,3, 922 // 1,0,0,2,3,0,1,1,4,2,2,1,2,3,2,0 ] 923 // quantized per channel with q_dim=3 924 "[12,20,10, 3, 2,24, 9,10, 5,16,30,12, 3,10, 4,32," 925 " 8, 0,30, 3, 0,16,12,15,20,12, 0, 3, 9,20, 8, 8," 926 " 12,15,20, 0, 0, 0, 3,15,15, 8,40,12, 9, 5, 2,24," 927 " 4, 0, 0, 6, 6, 0, 3, 5,20, 8,20, 3, 6,15, 4, 0]", 928 "1", // stride w and h 929 "SAME", // padding type 930 "", // bias shape 931 "", // bias data 932 "[ 0.0 ]", // filter quantization min values 933 "[ 255.0 ]", // filter quantization max values 934 "[0.25, 0.2, 0.1, 0.3333333333, " 935 "0.5, 0.125, 0.33333333, 0.2, " 936 "0.2, 0.25, 0.1, 0.333333333, " 937 "0.3333333333, 0.2, 0.5, 0.125]", // filter quantization scales 938 "[ 0, 0, 0, 0]", // filter quantization zero-points 939 "3" // filter quantized axis 940 // (in case of per channel quantization) 941 ) 942 {} 943 }; 944 945 // Test for depthwise_multiplier different to one (M > 1) 946 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4_3_1Fixture, 947 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4_3_1") 948 { 949 RunTest<4, armnn::DataType::QAsymmS8>( 950 0, 951 { 3,3,3,4, 4,4,0,0, 0,3,4,3, 0,2,2,3, 952 3,0,3,0, 0,3,2,1, 4,1,2,2, 0,0,0,4, 953 3,2,2,2, 2,1,0,4, 4,3,2,4, 3,2,0,0, 954 4,1,4,4, 1,0,4,3, 3,2,0,3, 1,1,0,2}, 955 { 26,21,21, 7,12,17,28,21,20,22,25,26, 6,11,10,16, 956 16,16, 4,12, 7,18,28,27,30,20,12,14,16,19,17, 6, 957 12,12, 8, 0, 3,13,18,15,18,26,20,26,26,32,28,21, 958 0, 0, 0, 0, 2, 6, 6, 4, 2, 8, 6, 8,15,10,10,24, 959 20,21, 9, 7, 3, 6,15,16,17,22,17,22,17,18,14, 7, 960 18, 6,16,12,12,11,17,15,18,18,10,12,27,26,22,18, 961 27,28,12,10, 7, 3, 8,13, 8,12,14,16,26,24,24,24, 962 9, 9, 6, 0, 0, 0, 2, 6, 0, 0, 0, 0, 4, 8, 8,16, 963 26,24,17, 7, 2, 8,11,10,30,24,30,28,32,33,30,24, 964 20,11,16,12, 7, 9,17,13,20,14,16,18,31,36,33,29, 965 28,25,19, 9, 6,13,20,19, 2, 8, 6, 8,17,17,15,25, 966 12,15, 5, 3, 2, 6, 7, 7, 0, 0, 0, 0, 6, 2, 2, 6, 967 14,16, 7, 5, 1, 3, 3, 2,20,28,12,20,13,20,20,19, 968 9, 4,10, 4, 0, 4, 8, 6, 4,16,12,16,12,18,18,15, 969 11,12, 6, 4, 2, 8,10, 7, 0, 0, 0, 0, 9,14,14,14, 970 3, 4, 1, 1, 1, 3, 3, 2, 0, 0, 0, 0, 2, 4, 4, 8}); 971 } 972 973 struct DepthwiseConvolution2dWeightsPerChannelQuant4_3_2Fixture : DepthwiseConvolution2dFixture2 974 { DepthwiseConvolution2dWeightsPerChannelQuant4_3_2FixtureDepthwiseConvolution2dWeightsPerChannelQuant4_3_2Fixture975 DepthwiseConvolution2dWeightsPerChannelQuant4_3_2Fixture() 976 : DepthwiseConvolution2dFixture2("[ 1, 2, 2, 2 ]", // inputShape 977 "[ 1, 2, 2, 4 ]", // outputShape 978 "[ 1, 3, 3, 4 ]", // filterShape 979 // filter data is [ 0,1,2,3,4,5,6,7,8, 980 // 0,1,2,3,4,5,6,7,8, 981 // 0,1,2,3,4,5,6,7,8, 982 // 0,1,2,3,4,5,6,7,8 ] 983 // quantized per channel with q_dim=3 984 "[0, 5,20, 9,16,25,60,21,32," 985 " 0,10, 6,12,20,50,18,28,40," 986 " 0, 3, 8,15,40,15,24,35,80," 987 " 0, 4,10,30,12,20,30,70,24]", 988 "1", // stride w and h 989 "SAME", // padding type 990 "", // bias shape 991 "", // bias data 992 "[ 0.0 ]", // filter quantization min values 993 "[ 255.0 ]", // filter quantization max values 994 "[0.25, 0.2, 0.1, 0.3333333333]", // filter quantization scales 995 "[ 0, 0, 0, 0]", // filter quantization zero-points 996 "3" // filter quantized axis 997 // (in case of per channel quantization) 998 ) 999 {} 1000 }; 1001 1002 // An easy test with M > 1 for debugging 1003 TEST_CASE_FIXTURE(DepthwiseConvolution2dWeightsPerChannelQuant4_3_2Fixture, 1004 "ParseDepthwiseConv2DFilterWeightsPerChannelQuant4_3_2") 1005 { 1006 RunTest<4, armnn::DataType::QAsymmS8>( 1007 0, 1008 { 0,1,2,3,4,5,6,7}, 1009 { 38,50,76,92,44,56,66,37,56,50,37,53,62,74,45,61}); 1010 } 1011 1012 } // end of TEST_SUITE("TensorflowLiteParser_DepthwiseConvolution2D") 1013