From 98e383eadf4e670d057ad725c7fe7924fea8e36b Mon Sep 17 00:00:00 2001 From: Idriss Chaouch Date: Mon, 28 Aug 2023 14:28:31 +0100 Subject: IVGCVSW-7525 Add broadcast_to operator Signed-off-by: Idriss Chaouch Signed-off-by: Narumol Prangnawarat Change-Id: I94ec5f9120b2d736fdf98d00ec5137a4efd739b8 --- .../test/BroadcastToEndToEndTestImpl.hpp | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/backends/backendsCommon/test/BroadcastToEndToEndTestImpl.hpp (limited to 'src/backends/backendsCommon/test/BroadcastToEndToEndTestImpl.hpp') diff --git a/src/backends/backendsCommon/test/BroadcastToEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/BroadcastToEndToEndTestImpl.hpp new file mode 100644 index 0000000000..3b2c47fb94 --- /dev/null +++ b/src/backends/backendsCommon/test/BroadcastToEndToEndTestImpl.hpp @@ -0,0 +1,149 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once +#include "armnn/INetwork.hpp" +#include "armnnUtils/QuantizeHelper.hpp" +#include "ElementwiseBinaryEndToEndTestImpl.hpp" +#include "Optimizer.hpp" +#include +#include +#include + +namespace +{ + using namespace armnn; + armnn::INetworkPtr CreateBroadcastToNetwork(BroadcastToDescriptor& descriptor, + const armnn::TensorInfo& inputInfo, + const armnn::TensorInfo& outputInfo) + { + INetworkPtr network(INetwork::Create()); + IConnectableLayer* inputLayer = network->AddInputLayer(0, "input"); + IConnectableLayer* broadcastLayer = network->AddBroadcastToLayer(descriptor, "broadcast_to"); + IConnectableLayer* outputLayer = network->AddOutputLayer(0, "output"); + Connect(inputLayer, broadcastLayer, inputInfo, 0, 0); + Connect(broadcastLayer, outputLayer, outputInfo, 0, 0); + return network; + } + + armnn::INetworkPtr CreateBroadcastToNetworkWithElementWiseBinary(BroadcastToDescriptor& descriptor, + const ElementwiseBinaryDescriptor& + elementWiseDescriptor, + const armnn::TensorInfo& inputInfo, + const armnn::TensorInfo& inputInfoElementWise, + const armnn::TensorInfo& outputInfo) + { + INetworkPtr network(INetwork::Create()); + IConnectableLayer* inputLayer = network->AddInputLayer(0, "input"); + IConnectableLayer* inputLayerElementWise = network->AddInputLayer(1, "inputElementWiseBinary"); + IConnectableLayer* broadcastLayer = network->AddBroadcastToLayer(descriptor, "broadcast_to"); + IConnectableLayer* multiplicationLayer = + network->AddElementwiseBinaryLayer(elementWiseDescriptor, + "multiplication"); + IConnectableLayer* outputLayer = network->AddOutputLayer(0, "output"); + Connect(inputLayer, broadcastLayer, inputInfo, 0, 0); + Connect(inputLayerElementWise, multiplicationLayer, + inputInfoElementWise, 0, 1); + Connect(broadcastLayer, multiplicationLayer, inputInfo, 0, 0); + Connect(multiplicationLayer, outputLayer, outputInfo, 0, 0); + return network; + } + + template > + void BroadcastToEndToEnd(const std::vector& backends) + { + float qScale = 1.0f; + int32_t qOffset = 0; + bool qConst = true; + + const TensorShape inputTensorShape = { {1, 4} }; + const TensorShape outputTensorShape = { {4, 4} }; + + TensorInfo inputInfo (inputTensorShape, ArmnnType, qScale, + qOffset, qConst); + TensorInfo outputInfo (outputTensorShape, ArmnnType,qScale, + qOffset); + + std::vector inputData = armnnUtils::QuantizedVector({ + 65, 144, 91, 161 + }, qScale, qOffset); + + std::vector expectedOutputData = armnnUtils::QuantizedVector({ + 65, 144, 91, 161, + 65, 144, 91, 161, + 65, 144, 91, 161, + 65, 144, 91, 161 + }, qScale, qOffset); + + auto descriptor = armnn::BroadcastToDescriptor(armnn::TensorShape({ 4, 4 })); + CHECK(descriptor.m_BroadcastToShape == outputTensorShape); + INetworkPtr network = CreateBroadcastToNetwork(descriptor, inputInfo, outputInfo); + + std::map> inputTensor = { { 0, inputData } }; + std::map> expectedOutputTensor = { { 0, expectedOutputData } }; + EndToEndLayerTestImpl(std::move(network),inputTensor, + expectedOutputTensor, backends); + } + + template > + void BroadcastToEndToEndElementWiseBinary(const std::vector& backends) + { + float qScale = 1.0f; + int32_t qOffset = 0; + bool qConst = true; + + const TensorShape inputTensorShape = { {1, 4} }; + const TensorShape outputTensorShape = { {4, 4} }; + + const TensorInfo inputInfo (inputTensorShape, ArmnnType, qScale, + qOffset, qConst); + const TensorInfo inputInfoElementWise (outputTensorShape, ArmnnType, qScale, + qOffset, qConst); + const TensorInfo outputInfo (outputTensorShape, ArmnnType,qScale, + qOffset); + + std::vector inputData = armnnUtils::QuantizedVector({ + 65, 144, 91, 161 + }, qScale, qOffset); + + std::vector inputDataElementWise = armnnUtils::QuantizedVector({ + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 + }, qScale, qOffset); + + std::vector expectedOutputData = armnnUtils::QuantizedVector({ + 65, 144, 91, 161, + 65, 144, 91, 161, + 65, 144, 91, 161, + 65, 144, 91, 161 + }, qScale, qOffset); + + auto descriptor = armnn::BroadcastToDescriptor(armnn::TensorShape({ 4, 4 })); + CHECK(descriptor.m_BroadcastToShape == outputTensorShape); + INetworkPtr network = CreateBroadcastToNetworkWithElementWiseBinary(descriptor, + BinaryOperation::Mul, + inputInfo, + inputInfoElementWise, + outputInfo); + // Create ArmNN runtime + IRuntimePtr run = IRuntime::Create(IRuntime::CreationOptions()); + + // Optimise ArmNN network + IOptimizedNetworkPtr optNet = Optimize(*network, {Compute::CpuRef}, + run->GetDeviceSpec()); + + Graph& graph = GetGraphForTesting(optNet.get()); + + Optimizer::Pass(graph, + armnn::MakeOptimizations(armnn::optimizations::BroadcastToOptimizationLayer())); + + std::map> inputTensor = { { 0, inputData }, {1, inputDataElementWise} }; + std::map> expectedOutputTensor = { { 0, expectedOutputData } }; + EndToEndLayerTestImpl(std::move(network),inputTensor, + expectedOutputTensor, backends); + } + +} // anonymous namespace \ No newline at end of file -- cgit v1.2.1