// // Copyright © 2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "TosaRefLayerSupport.hpp" #include #include #include #include #include #include #include namespace armnn { static bool IsTosaLayerSupported(TosaSerializationOperator* op, const std::vector& inputs, const std::vector& outputs, Optional reasonIfUnsupported) { switch(op->GetOp()) { case tosa::Op_ADD: { bool supported = true; std::array supportedAttributes = { Attribute_NONE }; // Check Attribute from operator (GetAttribute) supported &= CheckSupportRule(TosaOperatorAttributeOfAny(op, supportedAttributes), reasonIfUnsupported, std::string("TOSA Reference addition: operator has an unsupported attribute.").c_str()); std::array supportedTypes = { DType_BOOL, DType_UINT8, DType_INT4, DType_INT8, DType_INT16, DType_INT32, DType_FLOAT, DType_UINT16 }; for (auto tensor : inputs) { // Check Dtype from tensor (GetDtype) supported &= CheckSupportRule(TosaTypeAnyOf(tensor, supportedTypes), reasonIfUnsupported, std::string("TOSA Reference addition: " + tensor->GetName() + " is not a supported type.").c_str()); // Check Shape from tensor (GetShape) supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(tensor), reasonIfUnsupported, std::string("Tosa Reference addition: " + tensor->GetName() + " Shape.Size()" " outside bounds of between Zero and MaxNumOfTensorDimensions.").c_str()); } // Check Dtype from tensor (GetDtype) supported &= CheckSupportRule(TosaTypeAnyOf(outputs[0], supportedTypes), reasonIfUnsupported, std::string("TOSA Reference addition: " + outputs[0]->GetName() + " is not a supported type.").c_str()); // Check Shape from tensor (GetShape) supported &= CheckSupportRule(TosaTensorNumDimensionsWithinBounds(outputs[0]), reasonIfUnsupported, std::string("Tosa Reference addition: " + outputs[0]->GetName() + " Shape.Size()" " outside bounds of between Zero and MaxNumOfTensorDimensions.").c_str()); return supported; } default: SetValueChecked(reasonIfUnsupported, "Operation is currently unsupported by the TOSA Reference Backend."); return false; } } bool TosaRefLayerSupport::IsLayerSupported(const LayerType& type, const std::vector& infos, const BaseDescriptor& descriptor, const Optional& lstmParamsInfo, const Optional& quantizedLstmInputParamsInfo, Optional reasonIfUnsupported) const { IgnoreUnused(lstmParamsInfo); IgnoreUnused(quantizedLstmInputParamsInfo); // Setup Inputs const auto input0 = infos[0]; const TensorInfo* ptr0 = &input0; const auto input1 = infos[1]; const TensorInfo* ptr1 = &input1; std::vector inputInfos = {ptr0, ptr1}; // Setup Outputs const auto output = infos[2]; const TensorInfo* ptr2 = &output; std::vector outputInfos = {ptr2}; auto mappings = GetTosaMapping(type, inputInfos, outputInfos, descriptor); // Loop through block and get each tensor and operator for (long unsigned int i = 0; i < mappings->GetOperators().size(); ++i) { // While looping over operators check for op_UNKNOWN which is unsupported if (mappings->GetOperators()[i]->GetOp() == tosa::Op_UNKNOWN) { return false;} // Loop over operators and get GetInput/OutputTensorNames, loop over resulting names and // use GetTensorByName to pass pointers to tensors on to the IsTosaLayerSupported() std::vector inputTensorsVect; for (const auto& name : mappings->GetOperators()[i]->GetInputTensorNames()) { inputTensorsVect.push_back(mappings->GetTensorByName(name)); } std::vector outputTensorsVect; for (const auto& name : mappings->GetOperators()[i]->GetOutputTensorNames()) { outputTensorsVect.push_back(mappings->GetTensorByName(name)); } if (!IsTosaLayerSupported(mappings->GetOperators()[i], inputTensorsVect, outputTensorsVect, reasonIfUnsupported)) { return false; } } return true; } } // namespace armnn