1 // 2 // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 7 #include <armnn/Optional.hpp> 8 #include <armnn/Types.hpp> 9 #include <tosaReference/TosaRefLayerSupport.hpp> 10 11 #include <doctest/doctest.h> 12 13 #include <string> 14 15 using namespace armnn; 16 17 TEST_SUITE("TosaRefLayerSupported") 18 { 19 20 TEST_CASE("IsLayerSupportedTosaReferenceAddition") 21 { 22 TensorShape shape0 = {1,1,3,4}; 23 TensorShape shape1 = {1,1,3,4}; 24 TensorShape outShape = {1,1,3,4}; 25 TensorInfo in0(shape0, DataType::Float32); 26 TensorInfo in1(shape1, DataType::Float32); 27 TensorInfo out(outShape, DataType::Float32); 28 29 BaseDescriptor desc; 30 TosaRefLayerSupport supportChecker; 31 std::string reasonIfNotSupported; 32 auto supported = supportChecker.IsLayerSupported(LayerType::Addition, 33 {in0, in1, out}, 34 desc, 35 EmptyOptional(), 36 EmptyOptional(), 37 reasonIfNotSupported); 38 39 CHECK(supported); 40 } 41 42 TEST_CASE("IsLayerSupportedTosaReferenceAdditionUnsupported") 43 { 44 TensorShape shape0 = {1,1,3,4}; 45 TensorShape shape1 = {4}; 46 TensorShape outShape = {1,1,3,4}; 47 TensorInfo in0(shape0, DataType::Signed64); 48 TensorInfo in1(shape1, DataType::Signed64); 49 TensorInfo out(outShape, DataType::Signed64); 50 51 BaseDescriptor desc; 52 TosaRefLayerSupport supportChecker; 53 std::string reasonIfNotSupported; 54 auto supported = supportChecker.IsLayerSupported(LayerType::Addition, 55 {in0, in1, out}, 56 desc, 57 EmptyOptional(), 58 EmptyOptional(), 59 reasonIfNotSupported); 60 61 CHECK(!supported); 62 } 63 64 TEST_CASE("IsLayerSupportedTosaReferenceConcat") 65 { 66 TensorShape input0Shape = { 2, 3, 2, 2 }; 67 TensorShape input1Shape = { 2, 3, 2, 2 }; 68 TensorShape outputShape = { 2, 6, 2, 2 }; 69 TensorInfo input0Info(input0Shape, DataType::Float32); 70 TensorInfo input1Info(input1Shape, DataType::Float32); 71 TensorInfo outputInfo(outputShape, DataType::Float32); 72 73 OriginsDescriptor descriptor; 74 std::vector<TensorShape> shapes = {input0Shape, input1Shape} ; 75 unsigned int concatAxis = 1; 76 descriptor = CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatAxis); 77 78 TosaRefLayerSupport supportChecker; 79 std::string reasonIfNotSupported; 80 auto supported = supportChecker.IsLayerSupported(LayerType::Concat, 81 {input0Info, input1Info, outputInfo}, 82 descriptor, 83 EmptyOptional(), 84 EmptyOptional(), 85 reasonIfNotSupported); 86 87 CHECK(supported); 88 } 89 90 TEST_CASE("IsLayerSupportedTosaReferenceConcatUnsupported") 91 { 92 TensorShape input0Shape = { 2, 3, 2, 2 }; 93 TensorShape input1Shape = { 2, 3, 2, 2 }; 94 TensorShape outputShape = { 2, 6, 2, 2 }; 95 TensorInfo input0Info(input0Shape, armnn::DataType::QAsymmU8); 96 TensorInfo input1Info(input1Shape, armnn::DataType::QAsymmU8); 97 TensorInfo outputInfo(outputShape, armnn::DataType::QAsymmU8); 98 99 OriginsDescriptor descriptor; 100 std::vector<armnn::TensorShape> shapes = {input0Shape, input1Shape} ; 101 unsigned int concatAxis = 1; 102 descriptor = armnn::CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatAxis); 103 104 TosaRefLayerSupport supportChecker; 105 std::string reasonIfNotSupported; 106 auto supported = supportChecker.IsLayerSupported(LayerType::Concat, 107 {input0Info, input1Info, outputInfo}, 108 descriptor, 109 EmptyOptional(), 110 EmptyOptional(), 111 reasonIfNotSupported); 112 113 CHECK(!supported); 114 } 115 116 TEST_CASE("IsLayerSupportedTosaReferenceConstant") 117 { 118 TensorInfo outputInfo({1,1,3,4}, DataType::Float32); 119 120 TosaRefLayerSupport supportChecker; 121 std::string reasonIfNotSupported; 122 auto supported = supportChecker.IsLayerSupported(LayerType::Constant, 123 {outputInfo}, 124 BaseDescriptor(), 125 EmptyOptional(), 126 EmptyOptional(), 127 reasonIfNotSupported); 128 129 CHECK(supported); 130 } 131 132 TEST_CASE("IsLayerSupportedTosaReferenceConstantUnsupported") 133 { 134 TensorInfo outputInfo({1,1,3,4}, DataType::Signed64); 135 136 TosaRefLayerSupport supportChecker; 137 std::string reasonIfNotSupported; 138 auto supported = supportChecker.IsLayerSupported(LayerType::Constant, 139 {outputInfo}, 140 BaseDescriptor(), 141 EmptyOptional(), 142 EmptyOptional(), 143 reasonIfNotSupported); 144 145 CHECK(!supported); 146 } 147 148 TEST_CASE("IsLayerSupportedTosaReferenceConv2d") 149 { 150 TensorInfo inputInfo ({ 1, 5, 5, 1 }, DataType::Float32); 151 TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Float32); 152 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32); 153 TensorInfo biasesInfo ({ 1 }, DataType::Float32); 154 155 Convolution2dDescriptor desc; 156 desc.m_BiasEnabled = true; 157 158 TosaRefLayerSupport supportChecker; 159 std::string reasonIfNotSupported; 160 auto supported = supportChecker.IsLayerSupported(LayerType::Convolution2d, 161 {inputInfo, outputInfo, weightsInfo, biasesInfo}, 162 desc, 163 EmptyOptional(), 164 EmptyOptional(), 165 reasonIfNotSupported); 166 167 CHECK(supported); 168 } 169 170 TEST_CASE("IsLayerSupportedTosaReferenceConv2dUnsupported") 171 { 172 // If inputs and weights are Fp32, output must match. 173 TensorInfo inputInfo ({ 1, 5, 5, 1 }, DataType::Float32); 174 TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Signed64); 175 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true); 176 TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true); 177 178 Convolution2dDescriptor desc; 179 desc.m_BiasEnabled = true; 180 181 TosaRefLayerSupport supportChecker; 182 std::string reasonIfNotSupported; 183 auto supported = supportChecker.IsLayerSupported(LayerType::Convolution2d, 184 {inputInfo, outputInfo, weightsInfo, biasesInfo}, 185 desc, 186 EmptyOptional(), 187 EmptyOptional(), 188 reasonIfNotSupported); 189 190 CHECK(!supported); 191 } 192 193 TEST_CASE("IsLayerSupportedTosaReferenceMultiplication") 194 { 195 TensorShape shape0 = {1,1,3,4}; 196 TensorShape shape1 = {1,1,3,4}; 197 TensorShape outShape = {1,1,3,4}; 198 TensorInfo in0(shape0, armnn::DataType::Float32); 199 TensorInfo in1(shape1, armnn::DataType::Float32); 200 TensorInfo out(outShape, armnn::DataType::Float32); 201 202 BaseDescriptor desc; 203 TosaRefLayerSupport supportChecker; 204 std::string reasonIfNotSupported; 205 auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Multiplication, 206 {in0, in1, out}, 207 desc, 208 armnn::EmptyOptional(), 209 armnn::EmptyOptional(), 210 reasonIfNotSupported); 211 212 CHECK(supported); 213 } 214 215 TEST_CASE("IsLayerSupportedTosaReferenceMultiplicationUnsupported") 216 { 217 TensorShape shape0 = {1,1,3,4}; 218 TensorShape shape1 = {1,2,3,4}; 219 TensorShape outShape = {1,1,3,4}; 220 TensorInfo in0(shape0, armnn::DataType::Signed64); 221 TensorInfo in1(shape1, armnn::DataType::Signed64); 222 TensorInfo out(outShape, armnn::DataType::Signed64); 223 224 BaseDescriptor desc; 225 TosaRefLayerSupport supportChecker; 226 std::string reasonIfNotSupported; 227 auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Multiplication, 228 {in0, in1, out}, 229 desc, 230 armnn::EmptyOptional(), 231 armnn::EmptyOptional(), 232 reasonIfNotSupported); 233 234 CHECK(!supported); 235 } 236 237 TEST_CASE("IsLayerSupportedTosaReferenceMaxPooling2d") 238 { 239 TensorShape inShape = {1,1,3,4}; 240 TensorShape outShape = {1,1,3,4}; 241 TensorInfo in(inShape, DataType::Float32); 242 TensorInfo out(outShape, DataType::Float32); 243 244 Pooling2dDescriptor desc; 245 desc.m_PoolHeight = 1; 246 desc.m_PoolWidth = 1; 247 desc.m_StrideX = 1; 248 desc.m_StrideY = 1; 249 desc.m_PoolType = PoolingAlgorithm::Max; 250 251 TosaRefLayerSupport supportChecker; 252 std::string reasonIfNotSupported; 253 auto supported = supportChecker.IsLayerSupported(LayerType::Pooling2d, 254 {in, out}, 255 desc, 256 EmptyOptional(), 257 EmptyOptional(), 258 reasonIfNotSupported); 259 260 CHECK(supported); 261 } 262 263 TEST_CASE("IsLayerSupportedTosaReferenceAvgPooling2d_IgnoreValue") 264 { 265 TensorShape inShape = {1,1,3,4}; 266 TensorShape outShape = {1,1,3,4}; 267 TensorInfo in(inShape, DataType::Float32); 268 TensorInfo out(outShape, DataType::Float32); 269 270 Pooling2dDescriptor desc; 271 desc.m_PoolHeight = 1; 272 desc.m_PoolWidth = 1; 273 desc.m_StrideX = 1; 274 desc.m_StrideY = 1; 275 desc.m_PaddingMethod = PaddingMethod::IgnoreValue; 276 desc.m_PoolType = PoolingAlgorithm::Average; 277 278 TosaRefLayerSupport supportChecker; 279 std::string reasonIfNotSupported; 280 auto supported = supportChecker.IsLayerSupported(LayerType::Pooling2d, 281 {in, out}, 282 desc, 283 EmptyOptional(), 284 EmptyOptional(), 285 reasonIfNotSupported); 286 287 CHECK(supported); 288 } 289 290 TEST_CASE("IsLayerSupportedTosaReferenceMaxPooling2dUnsupported") 291 { 292 TensorShape inShape = {1,1,3,4}; 293 TensorShape outShape = {1,1,3,4}; 294 TensorInfo in(inShape, DataType::Signed64); 295 TensorInfo out(outShape, DataType::Signed64); 296 297 Pooling2dDescriptor desc; 298 TosaRefLayerSupport supportChecker; 299 std::string reasonIfNotSupported; 300 auto supported = supportChecker.IsLayerSupported(LayerType::Pooling2d, 301 {in, out}, 302 desc, 303 EmptyOptional(), 304 EmptyOptional(), 305 reasonIfNotSupported); 306 307 CHECK(!supported); 308 } 309 310 TEST_CASE("IsLayerSupportedTosaReferenceAvgPooling2dUnsupported_InputOutputDatatypeDifferent") 311 { 312 TensorShape inShape = {1,1,3,4}; 313 TensorShape outShape = {1,1,3,4}; 314 TensorInfo in(inShape, DataType::Float32); 315 TensorInfo out(outShape, DataType::Float16); 316 317 Pooling2dDescriptor desc; 318 desc.m_PaddingMethod = PaddingMethod::IgnoreValue; 319 desc.m_PoolType = PoolingAlgorithm::Average; 320 321 TosaRefLayerSupport supportChecker; 322 std::string reasonIfNotSupported; 323 auto supported = supportChecker.IsLayerSupported(LayerType::Pooling2d, 324 {in, out}, 325 desc, 326 EmptyOptional(), 327 EmptyOptional(), 328 reasonIfNotSupported); 329 330 CHECK(!supported); 331 } 332 333 TEST_CASE("IsLayerSupportedTosaReferenceReshape") 334 { 335 TensorShape inShape = {3,4}; 336 TensorShape outShape = {12}; 337 TensorInfo in(inShape, DataType::Float32); 338 TensorInfo out(outShape, DataType::Float32); 339 340 ReshapeDescriptor desc; 341 desc.m_TargetShape = {12}; 342 343 TosaRefLayerSupport supportChecker; 344 std::string reasonIfNotSupported; 345 auto supported = supportChecker.IsLayerSupported(LayerType::Reshape, 346 {in, out}, 347 desc, 348 EmptyOptional(), 349 EmptyOptional(), 350 reasonIfNotSupported); 351 352 CHECK(supported); 353 } 354 355 TEST_CASE("IsLayerSupportedTosaReferenceReshapeUnsupported") 356 { 357 TensorShape inShape = {3,4}; 358 TensorShape outShape = {12}; 359 TensorInfo in(inShape, DataType::Signed64); 360 TensorInfo out(outShape, DataType::Signed64); 361 362 ReshapeDescriptor desc; 363 desc.m_TargetShape = {12}; 364 365 TosaRefLayerSupport supportChecker; 366 std::string reasonIfNotSupported; 367 auto supported = supportChecker.IsLayerSupported(LayerType::Reshape, 368 {in, out}, 369 desc, 370 EmptyOptional(), 371 EmptyOptional(), 372 reasonIfNotSupported); 373 374 CHECK(!supported); 375 } 376 377 TEST_CASE("IsLayerSupportedTosaReferenceRsqrt") 378 { 379 TensorShape shape0 = {2,2}; 380 TensorShape outShape = {2,2}; 381 TensorInfo in0(shape0, DataType::Float32); 382 TensorInfo out(outShape, DataType::Float32); 383 384 ElementwiseUnaryDescriptor desc(UnaryOperation::Rsqrt); 385 TosaRefLayerSupport supportChecker; 386 std::string reasonIfNotSupported; 387 auto supported = supportChecker.IsLayerSupported(LayerType::ElementwiseUnary, 388 {in0, out}, 389 desc, 390 EmptyOptional(), 391 EmptyOptional(), 392 reasonIfNotSupported); 393 394 CHECK(supported); 395 } 396 397 TEST_CASE("IsLayerSupportedTosaReferenceRsqrtUnsupported") 398 { 399 TensorShape shape0 = {1,1,3,4}; 400 TensorShape outShape = {1,3,1,4}; 401 TensorInfo in0(shape0, DataType::Signed64); 402 TensorInfo out(outShape, DataType::Signed64); 403 404 ElementwiseUnaryDescriptor desc(UnaryOperation::Rsqrt); 405 TosaRefLayerSupport supportChecker; 406 std::string reasonIfNotSupported; 407 auto supported = supportChecker.IsLayerSupported(LayerType::ElementwiseUnary, 408 {in0, out}, 409 desc, 410 EmptyOptional(), 411 EmptyOptional(), 412 reasonIfNotSupported); 413 414 CHECK(!supported); 415 } 416 417 TEST_CASE("IsLayerSupportedTosaReferenceSlice") 418 { 419 TensorShape inShape = {3,2,3}; 420 TensorShape outShape = {2,1,3}; 421 TensorInfo in(inShape, DataType::Float32); 422 TensorInfo out(outShape, DataType::Float32); 423 424 SliceDescriptor descriptor; 425 descriptor.m_Begin = {1,0,0 }; 426 descriptor.m_Size = {2,1,3 }; 427 428 TosaRefLayerSupport supportChecker; 429 std::string reasonIfNotSupported; 430 auto supported = supportChecker.IsLayerSupported(LayerType::Slice, 431 {in, out}, 432 descriptor, 433 EmptyOptional(), 434 EmptyOptional(), 435 reasonIfNotSupported); 436 437 CHECK(supported); 438 } 439 440 TEST_CASE("IsLayerSupportedTosaReferenceSliceUnsupported") 441 { 442 TensorShape inShape = {3,2,3}; 443 TensorShape outShape = {2,1,3}; 444 TensorInfo in(inShape, DataType::Signed64); 445 TensorInfo out(outShape, DataType::Signed64); 446 447 SliceDescriptor descriptor; 448 descriptor.m_Begin = {1,0,0}; 449 descriptor.m_Size = {2,1,3}; 450 451 TosaRefLayerSupport supportChecker; 452 std::string reasonIfNotSupported; 453 auto supported = supportChecker.IsLayerSupported(LayerType::Slice, 454 {in, out}, 455 descriptor, 456 EmptyOptional(), 457 EmptyOptional(), 458 reasonIfNotSupported); 459 460 CHECK(!supported); 461 } 462 463 TEST_CASE("IsLayerSupportedTosaReferenceSubtraction") 464 { 465 TensorShape shape0 = {1,1,3,4}; 466 TensorShape shape1 = {1,1,3,4}; 467 TensorShape outShape = {1,1,3,4}; 468 TensorInfo in0(shape0, armnn::DataType::Float32); 469 TensorInfo in1(shape1, armnn::DataType::Float32); 470 TensorInfo out(outShape, armnn::DataType::Float32); 471 472 BaseDescriptor desc; 473 TosaRefLayerSupport supportChecker; 474 std::string reasonIfNotSupported; 475 auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Subtraction, 476 {in0, in1, out}, 477 desc, 478 armnn::EmptyOptional(), 479 armnn::EmptyOptional(), 480 reasonIfNotSupported); 481 482 CHECK(supported); 483 } 484 485 TEST_CASE("IsLayerSupportedTosaReferenceSubtractionUnsupported") 486 { 487 TensorShape shape0 = {1,1,3,4}; 488 TensorShape shape1 = {4}; 489 TensorShape outShape = {1,1,3,4}; 490 TensorInfo in0(shape0, armnn::DataType::Signed64); 491 TensorInfo in1(shape1, armnn::DataType::Signed64); 492 TensorInfo out(outShape, armnn::DataType::Signed64); 493 494 BaseDescriptor desc; 495 TosaRefLayerSupport supportChecker; 496 std::string reasonIfNotSupported; 497 auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Subtraction, 498 {in0, in1, out}, 499 desc, 500 armnn::EmptyOptional(), 501 armnn::EmptyOptional(), 502 reasonIfNotSupported); 503 504 CHECK(!supported); 505 } 506 507 TEST_CASE("IsLayerSupportedTosaReferenceTransposeConv2d") 508 { 509 TensorInfo inputInfo ({ 1, 3, 3, 1 }, DataType::Float32); 510 TensorInfo outputInfo({ 1, 5, 5, 1 }, DataType::Float32); 511 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32); 512 TensorInfo biasesInfo ({ 1 }, DataType::Float32); 513 514 TransposeConvolution2dDescriptor desc; 515 desc.m_StrideX = 1; 516 desc.m_StrideY = 1; 517 desc.m_BiasEnabled = true; 518 519 TosaRefLayerSupport supportChecker; 520 std::string reasonIfNotSupported; 521 auto supported = supportChecker.IsLayerSupported(LayerType::TransposeConvolution2d, 522 {inputInfo, outputInfo, weightsInfo, biasesInfo}, 523 desc, 524 EmptyOptional(), 525 EmptyOptional(), 526 reasonIfNotSupported); 527 CHECK(supported); 528 } 529 530 TEST_CASE("IsLayerSupportedTosaReferenceTransposeConv2dUnsupported") 531 { 532 // If inputs and weights are Fp32, output must match. 533 TensorInfo inputInfo ({ 1, 3, 3, 1 }, DataType::Float32); 534 TensorInfo outputInfo({ 1, 5, 5, 1 }, DataType::Float32); 535 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true); 536 TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true); 537 538 TransposeConvolution2dDescriptor desc; 539 desc.m_BiasEnabled = true; 540 541 TosaRefLayerSupport supportChecker; 542 std::string reasonIfNotSupported; 543 auto supported = supportChecker.IsLayerSupported(LayerType::TransposeConvolution2d, 544 {inputInfo, outputInfo, weightsInfo, biasesInfo}, 545 desc, 546 EmptyOptional(), 547 EmptyOptional(), 548 reasonIfNotSupported); 549 CHECK(!supported); 550 } 551 552 TEST_CASE("IsLayerSupportedTosaReferenceTranspose") 553 { 554 TensorShape inShape = { 1, 1, 5, 3 }; 555 TensorShape outShape = { 1, 5, 1, 3 }; 556 TensorInfo in(inShape, DataType::Float32); 557 TensorInfo out(outShape, DataType::Float32); 558 559 TransposeDescriptor transposeDescriptor = TransposeDescriptor({ 0, 2, 1 ,3 }); 560 561 TosaRefLayerSupport supportChecker; 562 std::string reasonIfNotSupported; 563 auto supported = supportChecker.IsLayerSupported(LayerType::Transpose, 564 {in, out}, 565 transposeDescriptor, 566 EmptyOptional(), 567 EmptyOptional(), 568 reasonIfNotSupported); 569 570 CHECK(supported); 571 } 572 573 TEST_CASE("IsLayerSupportedTosaReferenceTransposeUnsupported") 574 { 575 TensorShape inShape = { 1, 1, 5, 3 }; 576 TensorShape outShape = { 1, 5, 1, 3 }; 577 TensorInfo in(inShape, DataType::Signed64); 578 TensorInfo out(outShape, DataType::Signed64); 579 580 TransposeDescriptor transposeDescriptor = TransposeDescriptor({ 0, 2, 1 ,3 }); 581 582 TosaRefLayerSupport supportChecker; 583 std::string reasonIfNotSupported; 584 auto supported = supportChecker.IsLayerSupported(LayerType::Transpose, 585 {in, out}, 586 transposeDescriptor, 587 EmptyOptional(), 588 EmptyOptional(), 589 reasonIfNotSupported); 590 591 CHECK(!supported); 592 } 593 594 } 595