From 5b58e31109f661f70331048e22f8a66934e74d15 Mon Sep 17 00:00:00 2001 From: Kevin May Date: Thu, 15 Dec 2022 10:15:21 +0000 Subject: IVGCVSW-7170 Add Concat support to TOSA Reference Backend * Change comment for the unique tensor names in all tosa common operators Signed-off-by: Kevin May Change-Id: I247b4b2365d5f0173218c5dfd11fba12d2399959 --- .../backendsCommon/test/ConcatEndToEndTestImpl.hpp | 10 +-- src/backends/tosaCommon/TosaMappings.cpp | 5 ++ .../operatorMappings/AdditionOperator.cpp | 4 +- .../AvgPool2DIgnoreValueOperator.cpp | 4 +- .../tosaCommon/operatorMappings/CMakeLists.txt | 2 + .../tosaCommon/operatorMappings/ConcatOperator.cpp | 81 ++++++++++++++++++++++ .../tosaCommon/operatorMappings/ConcatOperator.hpp | 20 ++++++ .../tosaCommon/operatorMappings/Conv2dOperator.cpp | 10 +-- .../operatorMappings/Pooling2DOperator.cpp | 4 +- .../operatorMappings/ReshapeOperator.cpp | 4 +- .../tosaCommon/operatorMappings/SliceOperator.cpp | 4 +- .../operatorMappings/TosaCommonOperators.hpp | 1 + .../operatorMappings/TransposeConv2dOperator.cpp | 2 + .../tosaCommon/test/OneToOneMappingTests.cpp | 76 ++++++++++++++++++++ src/backends/tosaReference/TosaRefLayerSupport.cpp | 7 ++ .../tosaReference/test/TosaRefEndToEndTests.cpp | 42 +++++++++++ .../test/TosaRefLayerSupportTests.cpp | 52 ++++++++++++++ 17 files changed, 308 insertions(+), 20 deletions(-) create mode 100644 src/backends/tosaCommon/operatorMappings/ConcatOperator.cpp create mode 100644 src/backends/tosaCommon/operatorMappings/ConcatOperator.hpp diff --git a/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp index c8d20dace0..2614523e8e 100644 --- a/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp +++ b/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017,2022 Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -112,7 +112,7 @@ void ConcatDim0EndToEnd(const std::vector& backends) std::map> inputTensorData = {{ 0,inputData }, { 1,inputData }}; std::map> expectedOutputData = {{ 0,expectedOutput }}; - EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); } template @@ -174,7 +174,7 @@ void ConcatDim1EndToEnd(const std::vector& backends) std::map> inputTensorData = {{ 0,inputData }, { 1,inputData }}; std::map> expectedOutputData = {{ 0,expectedOutput }}; - EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); } template @@ -236,7 +236,7 @@ void ConcatDim2EndToEnd(const std::vector& backends) std::map> inputTensorData = {{ 0,inputData }, { 1,inputData }}; std::map> expectedOutputData = {{ 0,expectedOutput }}; - EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); } template> @@ -297,7 +297,7 @@ void ConcatDim3EndToEnd(const std::vector& backends) std::map> inputTensorData = {{ 0,inputData }, { 1,inputData }}; std::map> expectedOutputData = {{ 0,expectedOutput }}; - EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); } } // anonymous namespace diff --git a/src/backends/tosaCommon/TosaMappings.cpp b/src/backends/tosaCommon/TosaMappings.cpp index 7ecf7266ac..1452e4aefd 100644 --- a/src/backends/tosaCommon/TosaMappings.cpp +++ b/src/backends/tosaCommon/TosaMappings.cpp @@ -27,6 +27,11 @@ TosaSerializationBasicBlock* GetTosaMapping(const Layer* layer, { return ConvertAdditionToTosaOperator(layer, inputs, outputs); } + case LayerType::Concat: + { + auto concatDesc = PolymorphicDowncast(&descriptor); + return ConvertConcatToTosaOperator(layer, inputs, outputs, concatDesc); + } case LayerType::Constant: { return ConvertConstantToTosaOperator(layer, outputs); diff --git a/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp b/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp index 20ba146574..7014886d92 100644 --- a/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp @@ -18,14 +18,14 @@ TosaSerializationBasicBlock* ConvertAdditionToTosaOperator(const Layer* layer, // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { - // Get the layers connected to the input slots and determine unique layer names. + // Get the layers connected to the input slots and determine unique tensors names. Layer& connectedLayer0 = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); input0Name = GenerateUniqueName(connectedLayer0, 0); Layer& connectedLayer1 = layer->GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer(); input1Name = GenerateUniqueName(connectedLayer1, 1); - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp b/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp index d268c2faa4..61de0ae39a 100644 --- a/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp @@ -19,11 +19,11 @@ TosaSerializationBasicBlock* ConvertAvgPool2DIgnoreValueToTosaOperator(const Lay // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { - // Get the layers connected to the input slots and determine unique layer names. + // Get the layers connected to the input slots and determine unique tensors names. Layer& connectedInputLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); padInputName = GenerateUniqueName(connectedInputLayer, 0); - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. poolOutputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/CMakeLists.txt b/src/backends/tosaCommon/operatorMappings/CMakeLists.txt index 90c1a4f958..2443dc0585 100644 --- a/src/backends/tosaCommon/operatorMappings/CMakeLists.txt +++ b/src/backends/tosaCommon/operatorMappings/CMakeLists.txt @@ -8,6 +8,8 @@ list(APPEND armnnTosaBackendOperators_sources AdditionOperator.cpp AvgPool2DIgnoreValueOperator.hpp AvgPool2DIgnoreValueOperator.cpp + ConcatOperator.hpp + ConcatOperator.cpp ConstantOperator.hpp ConstantOperator.cpp Conv2dOperator.hpp diff --git a/src/backends/tosaCommon/operatorMappings/ConcatOperator.cpp b/src/backends/tosaCommon/operatorMappings/ConcatOperator.cpp new file mode 100644 index 0000000000..8c651be052 --- /dev/null +++ b/src/backends/tosaCommon/operatorMappings/ConcatOperator.cpp @@ -0,0 +1,81 @@ +// +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ConcatOperator.hpp" + +TosaSerializationBasicBlock* ConvertConcatToTosaOperator(const Layer* layer, + const std::vector& inputs, + const std::vector& outputs, + const OriginsDescriptor* concatDescriptor) +{ + auto numInputs = inputs.size(); + std::vector inputNames; + inputNames.reserve(numInputs); + std::string outputName = std::string("output0_"); + std::string blockName = std::string("Op_CONCAT_block_") + GetUniqueTosaMappingID(); + + // Set input names for validation purposes only. + if (layer == nullptr) + { + for (uint32_t i = 0; i < numInputs; ++i) + { + inputNames.push_back("input"+ std::to_string(i) +"_"); + } + } + // If a layer is present then the block will be used for execution, so input and output names need to be determined + // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. + else + { + // Get the layers connected to the input slots and determine unique tensor names. + for (uint32_t i = 0; i < numInputs; ++i) + { + Layer& connectedLayer = layer->GetInputSlot(i).GetConnectedOutputSlot()->GetOwningLayer(); + + std::string inputName = GenerateUniqueName(connectedLayer, i); + inputNames.push_back(inputName); + } + + // Determine unique output tensor name. + outputName = GenerateUniqueOutputName(*layer, 0); + } + + auto axis = static_cast(concatDescriptor->GetConcatAxis()); + TosaAxisAttribute attribute(axis); + + TosaSerializationOperator* op = new TosaSerializationOperator(Op_CONCAT, + Attribute_AxisAttribute, + &attribute, + inputNames, + {outputName}); + + std::vector tensors; + tensors.reserve(numInputs); + + for (uint32_t i = 0; i < numInputs; ++i) + { + // Only add input tensors for validation or when the connected layer is an input layer. + // As there can't be duplicate tensors and intermediate or constant tensors are created separately. + if(inputNames[i].find("input") != std::string::npos) + { + std::vector inputShape = GetTosaTensorShape(inputs[i]->GetShape()); + DType inputDType = ArmNNToDType(inputs[i]->GetDataType()); + tensors.push_back(new TosaSerializationTensor(inputNames[i], inputShape, inputDType, {})); + } + } + + std::vector outputShape0 = GetTosaTensorShape(outputs[0]->GetShape()); + DType outputDType0 = ArmNNToDType(outputs[0]->GetDataType()); + + TosaSerializationTensor* outputTensor0 = new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}); + tensors.push_back(outputTensor0); + + // operatorInputNames/operatorOutputNames ends up being the same as + // blockInputNames/blockOutputNames for one-to-one ArmNN to TOSA mappings + return new TosaSerializationBasicBlock(blockName, // name + {op}, // operators + tensors, // tensors + inputNames, // inputs + {outputName}); // outputs +} \ No newline at end of file diff --git a/src/backends/tosaCommon/operatorMappings/ConcatOperator.hpp b/src/backends/tosaCommon/operatorMappings/ConcatOperator.hpp new file mode 100644 index 0000000000..e6094ce03a --- /dev/null +++ b/src/backends/tosaCommon/operatorMappings/ConcatOperator.hpp @@ -0,0 +1,20 @@ +// +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +#include + +#include "TosaOperatorUtils.hpp" + +using namespace armnn; +using namespace tosa; + +TosaSerializationBasicBlock* ConvertConcatToTosaOperator(const Layer* layer, + const std::vector& inputs, + const std::vector& outputs, + const OriginsDescriptor* concatDescriptor); diff --git a/src/backends/tosaCommon/operatorMappings/Conv2dOperator.cpp b/src/backends/tosaCommon/operatorMappings/Conv2dOperator.cpp index 6fc1678c81..a7af08347a 100644 --- a/src/backends/tosaCommon/operatorMappings/Conv2dOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/Conv2dOperator.cpp @@ -24,21 +24,21 @@ TosaSerializationBasicBlock* ConvertConv2dToTosaOperator(const Layer* layer, inputNames.emplace_back("input2_"); } } + // If a layer is present then the block will be used for execution, so input and output names need to be + // determined using the previous and following layers so the graph is connected correctly. + // For validation this doesn't matter. else { - // If a layer is present then the block will be used for execution, so input and output names need to be - // determined using the previous and following layers so the graph is connected correctly. - // For validation this doesn't matter. + // Get the layer connected to the input slot and determine unique tensor names. for (uint32_t i = 0; i < inputs.size(); ++i) { - // Get the layer connected to the input slot and determine unique layer name. Layer& connectedLayer = layer->GetInputSlot(i).GetConnectedOutputSlot()->GetOwningLayer(); std::string inputName = GenerateUniqueName(connectedLayer, i); inputNames.push_back(inputName); } - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/Pooling2DOperator.cpp b/src/backends/tosaCommon/operatorMappings/Pooling2DOperator.cpp index ee02425c17..444d99a39e 100644 --- a/src/backends/tosaCommon/operatorMappings/Pooling2DOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/Pooling2DOperator.cpp @@ -21,11 +21,11 @@ TosaSerializationBasicBlock* ConvertPooling2DToTosaOperator(const Layer* layer, // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { - // Get the layers connected to the input slots and determine unique layer names. + // Get the layers connected to the input slots and determine unique tensor names. Layer& connectedInputLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); input0Name = GenerateUniqueName(connectedInputLayer, 0); - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/ReshapeOperator.cpp b/src/backends/tosaCommon/operatorMappings/ReshapeOperator.cpp index 3027e2ef42..10670ecb95 100644 --- a/src/backends/tosaCommon/operatorMappings/ReshapeOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/ReshapeOperator.cpp @@ -18,11 +18,11 @@ TosaSerializationBasicBlock* ConvertReshapeToTosaOperator(const Layer* layer, // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { - // Get the layers connected to the input slots and determine unique layer names. + // Get the layers connected to the input slots and determine unique tensor names. Layer& connectedLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); inputName = GenerateUniqueName(connectedLayer, 0); - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/SliceOperator.cpp b/src/backends/tosaCommon/operatorMappings/SliceOperator.cpp index 742ba88d73..b98576f47d 100644 --- a/src/backends/tosaCommon/operatorMappings/SliceOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/SliceOperator.cpp @@ -18,11 +18,11 @@ TosaSerializationBasicBlock* ConvertSliceToTosaOperator(const Layer* layer, // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { - // Get the layers connected to the input slots and determine unique layer names. + // Get the layers connected to the input slots and determine unique tensor names. Layer& connectedLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); inputName = GenerateUniqueName(connectedLayer, 0); - // Get the layer connected to the output slot and determine unique layer name. + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/operatorMappings/TosaCommonOperators.hpp b/src/backends/tosaCommon/operatorMappings/TosaCommonOperators.hpp index 1a9d6be9c0..052c54c3af 100644 --- a/src/backends/tosaCommon/operatorMappings/TosaCommonOperators.hpp +++ b/src/backends/tosaCommon/operatorMappings/TosaCommonOperators.hpp @@ -6,6 +6,7 @@ #pragma once #include "AdditionOperator.hpp" +#include "ConcatOperator.hpp" #include "ConstantOperator.hpp" #include "Conv2dOperator.hpp" #include "AvgPool2DIgnoreValueOperator.hpp" diff --git a/src/backends/tosaCommon/operatorMappings/TransposeConv2dOperator.cpp b/src/backends/tosaCommon/operatorMappings/TransposeConv2dOperator.cpp index 1ad8c9562f..c8af5c2926 100644 --- a/src/backends/tosaCommon/operatorMappings/TransposeConv2dOperator.cpp +++ b/src/backends/tosaCommon/operatorMappings/TransposeConv2dOperator.cpp @@ -22,9 +22,11 @@ TosaSerializationBasicBlock* ConvertTransposeConv2dToTosaOperator(const Layer* l // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter. if(layer != nullptr) { + // Get the layers connected to the input slots and determine unique tensor names. Layer& connectedInputLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer(); input0Name = GenerateUniqueName(connectedInputLayer, 0); + // Determine unique output tensor name. outputName = GenerateUniqueOutputName(*layer, 0); } diff --git a/src/backends/tosaCommon/test/OneToOneMappingTests.cpp b/src/backends/tosaCommon/test/OneToOneMappingTests.cpp index e74c638ee9..b3ab14a774 100644 --- a/src/backends/tosaCommon/test/OneToOneMappingTests.cpp +++ b/src/backends/tosaCommon/test/OneToOneMappingTests.cpp @@ -56,6 +56,82 @@ TEST_CASE("GetTosaMappingFromLayer_AdditionLayer") basicBlock, inputShape, outputShape, Op_ADD, Attribute_NONE, BaseDescriptor(), LayerType::Addition); } +TEST_CASE("GetTosaMapping_ConcatLayer") +{ + std::vector inputTensorShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 } }; + armnn::TensorInfo input0Info(inputTensorShapes[0], DataType::Float32); + armnn::TensorInfo input1Info(inputTensorShapes[1], DataType::Float32); + armnn::TensorInfo outputInfo({ 2, 6, 2, 2 }, DataType::Float32); + + armnn::OriginsDescriptor descriptor; + unsigned int concatAxis = 1; + descriptor.SetConcatAxis(concatAxis); + descriptor = armnn::CreateDescriptorForConcatenation(inputTensorShapes.begin(), + inputTensorShapes.end(), + concatAxis); + + TosaSerializationBasicBlock* basicBlock = + GetTosaMapping(nullptr, LayerType::Concat, {&input0Info,&input1Info}, {&outputInfo}, descriptor); + + std::vector> inputShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 }}; + std::vector> outputShape = { { 2, 6, 2, 2 } }; + + AssertTosaOneToOneMappingBasicBlock(basicBlock, + inputShapes, + outputShape, + Op_CONCAT, + Attribute_AxisAttribute, + descriptor, + LayerType::Concat); +} + +TEST_CASE("GetTosaMappingFromLayer_ConcatLayer") +{ + IRuntime::CreationOptions options; + IRuntimePtr runtime(IRuntime::Create(options)); + + // Builds up the structure of the network. + INetworkPtr net(INetwork::Create()); + + armnn::OriginsDescriptor descriptor; + unsigned int concatAxis = 1; + descriptor.SetConcatAxis(concatAxis); + std::vector inputTensorShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 } }; + descriptor = armnn::CreateDescriptorForConcatenation(inputTensorShapes.begin(), + inputTensorShapes.end(), + concatAxis); + + IConnectableLayer* input0 = net->AddInputLayer(0, "input0"); + IConnectableLayer* input1 = net->AddInputLayer(1, "input1"); + IConnectableLayer* concat = net->AddConcatLayer(descriptor, "concat"); + IConnectableLayer* output = net->AddOutputLayer(0, "output"); + + input0->GetOutputSlot(0).Connect(concat->GetInputSlot(0)); + input1->GetOutputSlot(0).Connect(concat->GetInputSlot(1)); + concat->GetOutputSlot(0).Connect(output->GetInputSlot(0)); + + + TensorInfo inputInfo0 = TensorInfo(inputTensorShapes[0], DataType::Float32, 0.0f, 0, true); + TensorInfo inputInfo1 = TensorInfo(inputTensorShapes[1], DataType::Float32, 0.0f, 0, true); + armnn::TensorInfo outputInfo({ 2, 6, 2, 2 }, DataType::Float32); + + input0->GetOutputSlot(0).SetTensorInfo(inputInfo0); + input1->GetOutputSlot(0).SetTensorInfo(inputInfo1); + concat->GetOutputSlot(0).SetTensorInfo(outputInfo); + + std::vector> inputShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 }}; + std::vector> outputShape = { { 2, 6, 2, 2 } }; + + TosaSerializationBasicBlock* basicBlock = GetTosaMappingFromLayer(PolymorphicDowncast(concat)); + AssertTosaOneToOneMappingBasicBlock(basicBlock, + inputShapes, + outputShape, + Op_CONCAT, + Attribute_AxisAttribute, + descriptor, + LayerType::Concat); +} + TEST_CASE("GetTosaMapping_ConstantLayer") { TensorInfo outputInfo = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true); diff --git a/src/backends/tosaReference/TosaRefLayerSupport.cpp b/src/backends/tosaReference/TosaRefLayerSupport.cpp index e5427ebc93..0d0d07a783 100644 --- a/src/backends/tosaReference/TosaRefLayerSupport.cpp +++ b/src/backends/tosaReference/TosaRefLayerSupport.cpp @@ -43,6 +43,13 @@ bool TosaRefLayerSupport::IsLayerSupported(const LayerType& type, inputInfos.push_back(&infos[1]); outputInfos.push_back(&infos[2]); break; + case LayerType::Concat: + for (unsigned int i = 0; i < infos.size() - 1; ++i) + { + inputInfos.push_back(&infos[i]); + } + outputInfos.push_back(&infos.back()); + break; case LayerType::Constant: outputInfos.push_back(&infos[0]); break; diff --git a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp index 49f2cb7319..a377293fbf 100644 --- a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp +++ b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp @@ -7,6 +7,7 @@ #include "backendsCommon/test/AdditionEndToEndTestImpl.hpp" #include "backendsCommon/test/Convolution2dEndToEndTestImpl.hpp" +#include "backendsCommon/test/ConcatEndToEndTestImpl.hpp" #include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" #include "backendsCommon/test/ReshapeEndToEndTestImpl.hpp" #include "backendsCommon/test/SliceEndToEndTestImpl.hpp" @@ -34,6 +35,47 @@ TEST_CASE("TosaRefAdditionEndtoEndTestFloat16") AdditionEndToEndFloat16(tosaDefaultBackends); } +// Concat +TEST_CASE("TosaRefConcatEndToEndDim0TestFloat32") +{ + ConcatDim0EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim0TestInt32") +{ + ConcatDim0EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim1TestFloat32") +{ + ConcatDim1EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim1TestInt32") +{ + ConcatDim1EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim2TestFloat32") +{ + ConcatDim2EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim2TestInt32") +{ + ConcatDim2EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim3TestFloat32") +{ + ConcatDim3EndToEnd(tosaDefaultBackends); +} + +TEST_CASE("TosaRefConcatEndToEndDim3TestInt32") +{ + ConcatDim3EndToEnd(tosaDefaultBackends); +} + // Conv2d TEST_CASE("TosaRefConv2dEndtoEndTestFloat32") { diff --git a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp index 3c3abc2af3..051965f541 100644 --- a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp +++ b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp @@ -61,6 +61,58 @@ TEST_CASE("IsLayerSupportedTosaReferenceAdditionUnsupported") CHECK(!supported); } +TEST_CASE("IsLayerSupportedTosaReferenceConcat") +{ + TensorShape input0Shape = { 2, 3, 2, 2 }; + TensorShape input1Shape = { 2, 3, 2, 2 }; + TensorShape outputShape = { 2, 6, 2, 2 }; + TensorInfo input0Info(input0Shape, DataType::Float32); + TensorInfo input1Info(input1Shape, DataType::Float32); + TensorInfo outputInfo(outputShape, DataType::Float32); + + OriginsDescriptor descriptor; + std::vector shapes = {input0Shape, input1Shape} ; + unsigned int concatAxis = 1; + descriptor = CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatAxis); + + TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(LayerType::Concat, + {input0Info, input1Info, outputInfo}, + descriptor, + EmptyOptional(), + EmptyOptional(), + reasonIfNotSupported); + + CHECK(supported); +} + +TEST_CASE("IsLayerSupportedTosaReferenceConcatUnsupported") +{ + TensorShape input0Shape = { 2, 3, 2, 2 }; + TensorShape input1Shape = { 2, 3, 2, 2 }; + TensorShape outputShape = { 2, 6, 2, 2 }; + TensorInfo input0Info(input0Shape, armnn::DataType::QAsymmU8); + TensorInfo input1Info(input1Shape, armnn::DataType::QAsymmU8); + TensorInfo outputInfo(outputShape, armnn::DataType::QAsymmU8); + + OriginsDescriptor descriptor; + std::vector shapes = {input0Shape, input1Shape} ; + unsigned int concatAxis = 1; + descriptor = armnn::CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatAxis); + + TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(LayerType::Concat, + {input0Info, input1Info, outputInfo}, + descriptor, + EmptyOptional(), + EmptyOptional(), + reasonIfNotSupported); + + CHECK(!supported); +} + TEST_CASE("IsLayerSupportedTosaReferenceConstant") { TensorInfo outputInfo({1,1,3,4}, DataType::Float32); -- cgit v1.2.1