diff options
Diffstat (limited to 'src/backends/tosaReference')
3 files changed, 313 insertions, 32 deletions
diff --git a/src/backends/tosaReference/TosaRefLayerSupport.cpp b/src/backends/tosaReference/TosaRefLayerSupport.cpp index a39bfb6c4d..ce4abbf921 100644 --- a/src/backends/tosaReference/TosaRefLayerSupport.cpp +++ b/src/backends/tosaReference/TosaRefLayerSupport.cpp @@ -13,24 +13,25 @@ #include <vector> #include <array> +#include <tuple> namespace armnn { -static bool RunTosaLayerChecks(TosaSerializationOperator* op, - const std::vector<TosaSerializationTensor*>& inputs, - const std::vector<TosaSerializationTensor*>& outputs, - const std::vector<Attribute>& supportedAttributes, - const std::vector<DType>& supportedTypes, - Optional<string&> reasonIfUnsupported) +static bool RunTosaLayerChecksSingleDataType(TosaSerializationOperator* op, + const std::vector<TosaSerializationTensor*>& inputs, + const std::vector<TosaSerializationTensor*>& outputs, + const std::vector<Attribute>& supportedAttributes, + const std::vector<DType>& supportedTypes, + Optional<string&> reasonIfUnsupported) { bool supported = true; - std::string opCode = std::to_string(op->GetOp()); + std::string opString = TosaOpToString(op->GetOp()); // Check Attribute from operator (GetAttribute) supported &= CheckSupportRule(TosaOperatorAttributeOfAny(op, supportedAttributes), reasonIfUnsupported, - std::string("TOSA Reference Operator: " + opCode + + std::string("TOSA Reference Operator: " + opString + " has an unsupported attribute.").c_str()); for (auto input : inputs) @@ -40,14 +41,14 @@ static bool RunTosaLayerChecks(TosaSerializationOperator* op, // Check Dtype from tensor (GetDtype) supported &= CheckSupportRule(TosaTypeAnyOf(input, supportedTypes), reasonIfUnsupported, - std::string("TOSA Reference Operator: " + opCode + " for input: " + + std::string("TOSA Reference Operator: " + opString + " for input: " + input->GetName() + " has an unsupported data type: " + dataTypeCode).c_str()); // Check Shape from tensor (GetShape) supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(input), reasonIfUnsupported, - std::string("Tosa Reference Operator: " + opCode + " for input: " + + std::string("Tosa Reference Operator: " + opString + " for input: " + input->GetName() + " exceeds MaxNumOfTensorDimensions.").c_str()); } @@ -58,20 +59,72 @@ static bool RunTosaLayerChecks(TosaSerializationOperator* op, // Check Dtype from tensor (GetDtype) supported &= CheckSupportRule(TosaTypeAnyOf(output, supportedTypes), reasonIfUnsupported, - std::string("TOSA Reference Operator: " + opCode + " for output: " + + std::string("TOSA Reference Operator: " + opString + " for output: " + output->GetName() + " has an unsupported data type: " + dataTypeCode).c_str()); // Check Shape from tensor (GetShape) supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(output), reasonIfUnsupported, - std::string("Tosa Reference Operator: " + opCode + " for output: " + + std::string("Tosa Reference Operator: " + opString + " for output: " + output->GetName() + " exceeds MaxNumOfTensorDimensions.").c_str()); } return supported; } +static bool RunTosaLayerChecksInputOutputDataType(TosaSerializationOperator* op, + const std::vector<TosaSerializationTensor*>& inputs, + const std::vector<TosaSerializationTensor*>& outputs, + const std::vector<Attribute>& supportedAttributes, + const std::vector<std::tuple<DType,DType>>& supportedMappingTypes, + Optional<string&> reasonIfUnsupported) +{ + bool supported = true; + + std::string opString = TosaOpToString(op->GetOp()); + + // Check Attribute from operator (GetAttribute) + supported &= CheckSupportRule(TosaOperatorAttributeOfAny(op, supportedAttributes), reasonIfUnsupported, + std::string("TOSA Reference Operator: " + opString + + " has an unsupported attribute.").c_str()); + + supported &= CheckSupportRule(TosaAssertSize(inputs, outputs), reasonIfUnsupported, + std::string("TOSA Reference Operator: " + opString + + " must have 1-to-1 mapping of inputs-to-outputs.").c_str()); + + for (uint32_t i = 0; i < inputs.size(); i++) + { + auto input = inputs[i]; + auto output = outputs[i]; + std::string inputDataTypeCode = std::to_string(input->GetDtype()); + std::string outputDataTypeCode = std::to_string(output->GetDtype()); + std::tuple<DType, DType> mappingType(input->GetDtype(), output->GetDtype()); + + // Check Dtype from tensor (GetDtype) + supported &= CheckSupportRule(TosaContainerContains(mappingType, supportedMappingTypes), + reasonIfUnsupported, + std::string("TOSA Reference Operator: " + opString + " for input: " + + input->GetName() + " and output: " + output->GetName() + + " has an unsupported input data type: " + inputDataTypeCode + + " to output data type: " + outputDataTypeCode).c_str()); + + // Check Shape from tensor (GetShape) + supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(input), + reasonIfUnsupported, + std::string("Tosa Reference Operator: " + opString + " for input: " + + input->GetName() + " exceeds MaxNumOfTensorDimensions.").c_str()); + + // Check Shape from tensor (GetShape) + supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(output), + reasonIfUnsupported, + std::string("Tosa Reference Operator: " + opString + " for output: " + + output->GetName() + " exceeds MaxNumOfTensorDimensions.").c_str()); + } + + return supported; +} + static bool IsTosaLayerSupported(TosaSerializationOperator* op, const std::vector<TosaSerializationTensor*>& inputs, const std::vector<TosaSerializationTensor*>& outputs, @@ -81,8 +134,6 @@ static bool IsTosaLayerSupported(TosaSerializationOperator* op, { case tosa::Op_ADD: { - bool supported = true; - std::vector<Attribute> supportedAttributes = { Attribute_NONE @@ -97,14 +148,84 @@ static bool IsTosaLayerSupported(TosaSerializationOperator* op, }; // Check the attribute, data types and bounds for inputs and outputs. - supported = RunTosaLayerChecks(op, - inputs, - outputs, - supportedAttributes, - supportedTypes, - reasonIfUnsupported); - - return supported; + return RunTosaLayerChecksSingleDataType(op, + inputs, + outputs, + supportedAttributes, + supportedTypes, + reasonIfUnsupported); + } + case tosa::Op_AVG_POOL2D: + { + std::vector<Attribute> supportedAttributes = + { + Attribute_PoolAttribute + }; + + std::vector<std::tuple<DType, DType>> supportedTypesMapping = + { + std::tuple<DType, DType>(DType_FP16, DType_FP16), + std::tuple<DType, DType>(DType_FP16, DType_FP32), + std::tuple<DType, DType>(DType_FP32, DType_FP32), + std::tuple<DType, DType>(DType_INT8, DType_INT32), + std::tuple<DType, DType>(DType_INT16, DType_INT32) + }; + + // Check the attribute, data types and bounds for inputs and outputs. + return RunTosaLayerChecksInputOutputDataType(op, + inputs, + outputs, + supportedAttributes, + supportedTypesMapping, + reasonIfUnsupported); + } + case tosa::Op_MAX_POOL2D: + { + std::vector<Attribute> supportedAttributes = + { + Attribute_PoolAttribute + }; + + std::vector<DType> supportedTypes = + { + DType_FP16, + DType_FP32, + DType_INT8, + DType_INT16 + }; + + // Check the attribute, data types and bounds for inputs and outputs. + return RunTosaLayerChecksSingleDataType(op, + inputs, + outputs, + supportedAttributes, + supportedTypes, + reasonIfUnsupported); + } + case tosa::Op_PAD: + { + std::vector<Attribute> supportedAttributes = + { + Attribute_PadAttribute + }; + + std::vector<DType> supportedTypes = + { + DType_FP16, + DType_FP32, + DType_INT8, + DType_INT16, + DType_INT32, + DType_BOOL + }; + + // Check the attribute, data types and bounds for inputs and outputs. + return RunTosaLayerChecksSingleDataType(op, + inputs, + outputs, + supportedAttributes, + supportedTypes, + reasonIfUnsupported); } default: SetValueChecked(reasonIfUnsupported, "Operation is currently unsupported by the TOSA Reference Backend."); @@ -136,6 +257,11 @@ bool TosaRefLayerSupport::IsLayerSupported(const LayerType& type, case LayerType::Input: case LayerType::Output: return true; + case LayerType::Pooling2d: + // Setup inputs and outputs + inputInfos.push_back(&infos[0]); + outputInfos.push_back(&infos[1]); + break; default: break; } diff --git a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp index 54d6db6cef..fbe1265fe3 100644 --- a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp +++ b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp @@ -6,27 +6,60 @@ #include "backendsCommon/test/EndToEndTestImpl.hpp" #include "backendsCommon/test/AdditionEndToEndTestImpl.hpp" +#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" #include <doctest/doctest.h> TEST_SUITE("TosaRefEndToEnd") { -std::vector<armnn::BackendId> tosaDefaultBackends = { "TosaRef" }; +std::vector<BackendId> tosaDefaultBackends = { "TosaRef" }; // Addition -TEST_CASE("TosaRefEndtoEndTestFloat32") +TEST_CASE("TosaRefAdditionEndtoEndTestFloat32") { - AdditionEndToEnd<armnn::DataType::Float32>(tosaDefaultBackends); + AdditionEndToEnd<DataType::Float32>(tosaDefaultBackends); } -TEST_CASE("TosaRefEndtoEndTestInt32") +TEST_CASE("TosaRefAdditionEndtoEndTestInt32") { - AdditionEndToEnd<armnn::DataType::Signed32>(tosaDefaultBackends); + AdditionEndToEnd<DataType::Signed32>(tosaDefaultBackends); } -TEST_CASE("TosaRefEndtoEndTestFloat16") +TEST_CASE("TosaRefAdditionEndtoEndTestFloat16") { - AdditionEndToEndFloat16<armnn::DataType::Float16>(tosaDefaultBackends); + AdditionEndToEndFloat16<DataType::Float16>(tosaDefaultBackends); +} + +// Max Pool 2D +TEST_CASE("TosaRefMaxPool2DEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd<DataType::Float32>(tosaDefaultBackends); +} + +TEST_CASE("TosaRefMaxPool2DEndtoEndTestFloat16") +{ + MaxPool2dEndToEndFloat16<DataType::Float16>(tosaDefaultBackends); +} + +TEST_CASE("TosaRefMaxPool2DIgnoreValueEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd<DataType::Float32>(tosaDefaultBackends, PaddingMethod::IgnoreValue); +} + +// Average Pool 2D +TEST_CASE("TosaRefAvgPool2DEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd<DataType::Float32>(tosaDefaultBackends); +} + +TEST_CASE("TosaRefAvgPool2DEndtoEndTestFloat16") +{ + AvgPool2dEndToEndFloat16<DataType::Float16>(tosaDefaultBackends); +} + +TEST_CASE("TosaRefAvgPool2DIgnoreValueEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd<DataType::Float32>(tosaDefaultBackends, PaddingMethod::IgnoreValue); } }
\ No newline at end of file diff --git a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp index 47f31380a5..48eca344bc 100644 --- a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp +++ b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp @@ -57,9 +57,131 @@ TEST_CASE("IsLayerSupportedTosaReferenceAdditionUnsupported") reasonIfNotSupported); CHECK(!supported); - REQUIRE(reasonIfNotSupported.find("TOSA Reference Operator: 14 for input: Op_ADD_input0_") != std::string::npos); - REQUIRE(reasonIfNotSupported.find("TOSA Reference Operator: 14 for input: Op_ADD_input1_") != std::string::npos); - REQUIRE(reasonIfNotSupported.find("TOSA Reference Operator: 14 for output: Op_ADD_output0_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_ADD for input: Op_ADD_input0_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_ADD for input: Op_ADD_input1_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_ADD for output: Op_ADD_output0_") != std::string::npos); +} + +TEST_CASE("IsLayerSupportedTosaReferenceMaxPooling2d") +{ + armnn::TensorShape inShape = {1,1,3,4}; + armnn::TensorShape outShape = {1,1,3,4}; + armnn::TensorInfo in(inShape, armnn::DataType::Float32); + armnn::TensorInfo out(outShape, armnn::DataType::Float32); + + armnn::Pooling2dDescriptor desc; + armnn::TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Pooling2d, + {in, out}, + desc, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + reasonIfNotSupported); + + CHECK(supported); +} + +TEST_CASE("IsLayerSupportedTosaReferenceAvgPooling2d_IgnoreValue") +{ + armnn::TensorShape inShape = {1,1,3,4}; + armnn::TensorShape outShape = {1,1,3,4}; + armnn::TensorInfo in(inShape, armnn::DataType::Float32); + armnn::TensorInfo out(outShape, armnn::DataType::Float32); + + armnn::Pooling2dDescriptor desc; + desc.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue; + desc.m_PoolType = armnn::PoolingAlgorithm::Average; + + armnn::TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Pooling2d, + {in, out}, + desc, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + reasonIfNotSupported); + + CHECK(supported); +} + +TEST_CASE("IsLayerSupportedTosaReferenceAvgPooling2d_InputOutputDatatypeDifferent") +{ + armnn::TensorShape inShape = {1,1,3,4}; + armnn::TensorShape outShape = {1,1,3,4}; + armnn::TensorInfo in(inShape, armnn::DataType::QAsymmS8); + armnn::TensorInfo out(outShape, armnn::DataType::Signed32); + + armnn::Pooling2dDescriptor desc; + desc.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue; + desc.m_PoolType = armnn::PoolingAlgorithm::Average; + + armnn::TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Pooling2d, + {in, out}, + desc, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + reasonIfNotSupported); + + CHECK(supported); +} + +TEST_CASE("IsLayerSupportedTosaReferenceMaxPooling2dUnsupported") +{ + armnn::TensorShape inShape = {1,1,3,4}; + armnn::TensorShape outShape = {1,1,3,4}; + armnn::TensorInfo in(inShape, armnn::DataType::Signed64); + armnn::TensorInfo out(outShape, armnn::DataType::Signed64); + + armnn::Pooling2dDescriptor desc; + armnn::TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Pooling2d, + {in, out}, + desc, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + reasonIfNotSupported); + + CHECK(!supported); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_MAX_POOL2D for input: Op_MAX_POOL2D_input0_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_MAX_POOL2D for output: Op_MAX_POOL2D_output0_") != std::string::npos); +} + +TEST_CASE("IsLayerSupportedTosaReferenceAvgPooling2dUnsupported_InputOutputDatatypeDifferent") +{ + armnn::TensorShape inShape = {1,1,3,4}; + armnn::TensorShape outShape = {1,1,3,4}; + armnn::TensorInfo in(inShape, armnn::DataType::Float32); + armnn::TensorInfo out(outShape, armnn::DataType::Float16); + + armnn::Pooling2dDescriptor desc; + desc.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue; + desc.m_PoolType = armnn::PoolingAlgorithm::Average; + + armnn::TosaRefLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(armnn::LayerType::Pooling2d, + {in, out}, + desc, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + reasonIfNotSupported); + + CHECK(!supported); + REQUIRE(reasonIfNotSupported.find( + "TOSA Reference Operator: Op_AVG_POOL2D for input: Op_PAD_intermediate0_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + " and output: Op_AVG_POOL2D_output0_") != std::string::npos); + REQUIRE(reasonIfNotSupported.find( + " has an unsupported input data type: 8 to output data type: 10") != std::string::npos); } } |