From bd18eab07a8f30492de1e462b1815189014cb8d5 Mon Sep 17 00:00:00 2001 From: Cathal Corbett Date: Tue, 15 Nov 2022 12:56:16 +0000 Subject: IVGCVSW-7345 Add Pooling2d support to TOSA Reference Backend Signed-off-by: Cathal Corbett Change-Id: I73a47e513fe2d064ef233b121a68ef2edf0396dc --- .../AvgPool2DIgnoreValueOperator.cpp | 107 +++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp (limited to 'src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp') diff --git a/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp b/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp new file mode 100644 index 0000000000..b3d2687c30 --- /dev/null +++ b/src/backends/tosaCommon/operatorMappings/AvgPool2DIgnoreValueOperator.cpp @@ -0,0 +1,107 @@ +// +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "Pooling2DOperator.hpp" + +TosaSerializationBasicBlock* ConvertAvgPool2DIgnoreValueToTosaOperator(const std::vector& inputs, + const std::vector& outputs, + bool isMain, + const Pooling2dDescriptor* poolDescriptor) +{ + + // A helper function with static global variables ensures uniqueness + // for dynamically generating input, output and block names + std::string padInputName = std::string("Op_PAD_input0_") + GetUniqueTosaMappingID(); + std::string padOutputName = std::string("Op_PAD_intermediate0_") + GetUniqueTosaMappingID(); + std::string poolOutputName = std::string("Op_AVG_POOL2D_output0_") + GetUniqueTosaMappingID(); + std::string blockName = std::string("Op_AVG_POOL2D_block_") + GetUniqueTosaMappingID(); + + // If it's the first block, overwrite block name with main. + if (isMain) + { + blockName = std::string("main"); + } + + std::vector paddings; + if (poolDescriptor->m_DataLayout == DataLayout::NHWC) + { + paddings = {0, + 0, + static_cast(poolDescriptor->m_PadTop), + static_cast(poolDescriptor->m_PadBottom), + static_cast(poolDescriptor->m_PadLeft), + static_cast(poolDescriptor->m_PadRight), + 0, + 0 + }; + } + else + { + paddings = {0, + 0, + 0, + 0, + static_cast(poolDescriptor->m_PadTop), + static_cast(poolDescriptor->m_PadBottom), + static_cast(poolDescriptor->m_PadLeft), + static_cast(poolDescriptor->m_PadRight) + }; + } + + TosaPadAttribute padAttribute(paddings, 0, 0.0f); + TosaSerializationOperator* opPad = new TosaSerializationOperator(Op_PAD, + Attribute_PadAttribute, + &padAttribute, + {padInputName}, + {padOutputName}); + + std::vector pad = {0, 0, 0, 0}; + std::vector kernel = {static_cast(poolDescriptor->m_PoolHeight), + static_cast(poolDescriptor->m_PoolWidth)}; + std::vector stride = {static_cast(poolDescriptor->m_StrideY), + static_cast(poolDescriptor->m_StrideX)}; + TosaPoolAttribute poolAttribute(pad, kernel, stride, 0, 0, ArmNNToDType(inputs[0]->GetDataType())); + + TosaSerializationOperator* opPool = new TosaSerializationOperator(Op_AVG_POOL2D, + Attribute_PoolAttribute, + &poolAttribute, + {padOutputName}, + {poolOutputName}); + + std::vector inputShape = GetTosaTensorShape(inputs[0]->GetShape()); + DType inputDType = ArmNNToDType(inputs[0]->GetDataType()); + + std::vector outputShape = GetTosaTensorShape(outputs[0]->GetShape()); + DType outputDType = ArmNNToDType(outputs[0]->GetDataType()); + + std::vector intermediateShape; + if (poolDescriptor->m_DataLayout == DataLayout::NHWC) + { + intermediateShape = {inputShape[0], + inputShape[1] + paddings[2] + paddings[3], + inputShape[2] + paddings[4] + paddings[5], + inputShape[3]}; + } + else + { + intermediateShape = {inputShape[0], + inputShape[1], + inputShape[2] + paddings[4] + paddings[5], + inputShape[3] + paddings[6] + paddings[7]}; + } + + TosaSerializationTensor* inputTensor = new TosaSerializationTensor(padInputName, inputShape, inputDType, {}); + TosaSerializationTensor* intermediateTensor = new TosaSerializationTensor( + padOutputName, intermediateShape, inputDType, {}); + TosaSerializationTensor* outputTensor = new TosaSerializationTensor(poolOutputName, outputShape, outputDType, {}); + + // operatorInputNames/operatorOutputNames ends up being the same as + // blockInputNames/blockOutputNames for one-to-one ArmNN to Tosa mappings + return new TosaSerializationBasicBlock(blockName, // name + {opPad, opPool}, // operators + {inputTensor, intermediateTensor, outputTensor}, // tensors + {padInputName}, // inputs + {poolOutputName}); // outputs +} \ No newline at end of file -- cgit v1.2.1