From 70dc5e9dc375c2feb306c7e709078c9f61ef8b1a Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Tue, 5 Mar 2024 17:59:27 +0000 Subject: IVGCVSW-8233 ScatterNd End to End tests added Signed-off-by: Teresa Charlin Change-Id: Id89233954dd8da600c2f82e718df849b098c8af4 --- src/armnn/layers/ScatterNdLayer.cpp | 2 +- src/backends/backendsCommon/test/CMakeLists.txt | 1 + .../test/ScatterNdEndToEndTestImpl.hpp | 160 +++++++++++++++++++++ src/backends/reference/test/RefEndToEndTests.cpp | 44 ++++++ 4 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/backends/backendsCommon/test/ScatterNdEndToEndTestImpl.hpp diff --git a/src/armnn/layers/ScatterNdLayer.cpp b/src/armnn/layers/ScatterNdLayer.cpp index a0b270fba5..853b87f9db 100644 --- a/src/armnn/layers/ScatterNdLayer.cpp +++ b/src/armnn/layers/ScatterNdLayer.cpp @@ -77,7 +77,7 @@ void ScatterNdLayer::ValidateTensorShapesFromInputs() // No input tensor, only shape provided via input slot // In this case, we cannot validate the output shape from the input shape, but we can // validate that the dimensions of shape and output tensor matched - unsigned int shapeDims = GetInputSlot(0).GetTensorInfo().GetNumDimensions(); + unsigned int shapeDims = GetInputSlot(0).GetTensorInfo().GetShape().GetNumElements(); unsigned int outputDims = GetOutputSlot(0).GetTensorInfo().GetNumDimensions(); if (shapeDims != outputDims) diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 66bf6a084e..4438021938 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -56,6 +56,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources ReshapeEndToEndTestImpl.hpp ResizeEndToEndTestImpl.hpp RuntimeTestImpl.hpp + ScatterNdEndToEndTestImpl.hpp SliceEndToEndTestImpl.hpp SoftmaxEndToEndTestImpl.hpp SpaceToDepthEndToEndTestImpl.cpp diff --git a/src/backends/backendsCommon/test/ScatterNdEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ScatterNdEndToEndTestImpl.hpp new file mode 100644 index 0000000000..3b796a0c21 --- /dev/null +++ b/src/backends/backendsCommon/test/ScatterNdEndToEndTestImpl.hpp @@ -0,0 +1,160 @@ +// +// Copyright © 2024 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +#include +#include + +#include + +using namespace armnn; + +namespace +{ + +template> +INetworkPtr CreateScatterNdNetwork(const TensorInfo& shapeInfo, + const TensorInfo& indicesInfo, + const TensorInfo& updatesInfo, + const TensorInfo& outputInfo, + const std::vector& indicesData, + const std::vector& updatesData, + const ScatterNdDescriptor& descriptor) +{ + INetworkPtr net(INetwork::Create()); + + IConnectableLayer* shapeLayer = net->AddInputLayer(0); + IConnectableLayer* indicesLayer = net->AddConstantLayer(ConstTensor(indicesInfo, indicesData)); + IConnectableLayer* updatesLayer = net->AddConstantLayer(ConstTensor(updatesInfo, updatesData)); + IConnectableLayer* scatterNdLayer = net->AddScatterNdLayer(descriptor, "scatterNd"); + IConnectableLayer* outputLayer = net->AddOutputLayer(0, "output"); + Connect(shapeLayer, scatterNdLayer, shapeInfo, 0, 0); + Connect(indicesLayer, scatterNdLayer, indicesInfo, 0, 1); + Connect(updatesLayer, scatterNdLayer, updatesInfo, 0, 2); + Connect(scatterNdLayer, outputLayer, outputInfo, 0, 0); + + return net; +} + +template> +void ScatterNd1DimUpdateWithInputEndToEnd(const std::vector& backends) +{ + float_t qScale = 1.f; + int32_t qOffset = 0; + + TensorInfo inputInfo({ 5 }, ArmnnType, qScale, qOffset, true); + TensorInfo indicesInfo({ 3, 1 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo updatesInfo({ 3 }, ArmnnType, qScale, qOffset, true); + TensorInfo outputInfo({ 5 }, ArmnnType, qScale, qOffset, false); + + std::vector inputData = armnnUtils::QuantizedVector({ 0, 0, 0, 0, 0 }, qScale, qOffset); + std::vector indicesData{0, 1, 2}; + std::vector updatesData = armnnUtils::QuantizedVector({ 1, 2, 3 }, qScale, qOffset); + std::vector expectedOutput = armnnUtils::QuantizedVector({ 1, 2, 3, 0, 0 }, qScale, qOffset); + + armnn::ScatterNdDescriptor descriptor(armnn::ScatterNdFunction::Update, true); + + INetworkPtr net = CreateScatterNdNetwork(inputInfo, indicesInfo, updatesInfo, outputInfo, + indicesData, updatesData, descriptor); + + CHECK(net); + + std::map> inputTensorData = {{ 0, inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput }}; + + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); +} + +template> +void ScatterNd1DimUpdateNoInputEndToEnd(const std::vector& backends) +{ + float_t qScale = 1.f; + int32_t qOffset = 0; + + TensorInfo shapeInfo({ 1 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo indicesInfo({ 3, 1 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo updatesInfo({ 3 }, ArmnnType, qScale, qOffset, true); + TensorInfo outputInfo({ 5 }, ArmnnType, qScale, qOffset, false); + + std::vector shapeData{ 5 }; + std::vector indicesData{ 0, 1, 2 }; + std::vector updatesData = armnnUtils::QuantizedVector({ 1, 2, 3 }, qScale, qOffset); + std::vector expectedOutput = armnnUtils::QuantizedVector({ 1, 2, 3, 0, 0 }, qScale, qOffset); + + armnn::ScatterNdDescriptor descriptor(armnn::ScatterNdFunction::Update, false); + + INetworkPtr net = CreateScatterNdNetwork(shapeInfo, indicesInfo, updatesInfo, outputInfo, + indicesData, updatesData, descriptor); + + CHECK(net); + + std::map> inputTensorData = {{ 0, shapeData }}; + std::map> expectedOutputData = {{ 0, expectedOutput }}; + + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); +} + +template> +void ScatterNd2DimUpdateWithInputEndToEnd(const std::vector& backends) +{ + float_t qScale = 1.f; + int32_t qOffset = 0; + + TensorInfo inputInfo({ 3, 3 }, ArmnnType, qScale, qOffset, true); + TensorInfo indicesInfo({ 3, 2 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo updatesInfo({ 3 }, ArmnnType, qScale, qOffset, true); + TensorInfo outputInfo({ 3, 3 }, ArmnnType, qScale, qOffset, false); + + std::vector inputData = armnnUtils::QuantizedVector({ 1, 1, 1, 1, 1, 1, 1, 1, 1 }, qScale, qOffset); + std::vector indicesData{0, 0, 1, 1, 2, 2}; + std::vector updatesData = armnnUtils::QuantizedVector({ 1, 2, 3 }, qScale, qOffset); + std::vector expectedOutput = armnnUtils::QuantizedVector({ 1, 1, 1, 1, 2, 1, 1, 1, 3 }, qScale, qOffset); + + armnn::ScatterNdDescriptor descriptor(armnn::ScatterNdFunction::Update, true); + + INetworkPtr net = CreateScatterNdNetwork(inputInfo, indicesInfo, updatesInfo, outputInfo, + indicesData, updatesData, descriptor); + + CHECK(net); + + std::map> inputTensorData = {{ 0, inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput }}; + + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); +} + +template> +void ScatterNd2DimUpdateNoInputEndToEnd(const std::vector& backends) +{ + float_t qScale = 1.f; + int32_t qOffset = 0; + + TensorInfo shapeInfo({ 2 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo indicesInfo({ 3, 2 }, DataType::Signed32, 1.0f, 0, true); + TensorInfo updatesInfo({ 3 }, ArmnnType, qScale, qOffset, true); + TensorInfo outputInfo({ 3, 3 }, ArmnnType, qScale, qOffset, false); + + std::vector shapeData{ 3, 3 }; + std::vector indicesData{0, 0, 1, 1, 2, 2}; + std::vector updatesData = armnnUtils::QuantizedVector({ 1, 2, 3 }, qScale, qOffset); + std::vector expectedOutput = armnnUtils::QuantizedVector({ 1, 0, 0, 0, 2, 0, 0, 0, 3 }, qScale, qOffset); + + armnn::ScatterNdDescriptor descriptor(armnn::ScatterNdFunction::Update, false); + + INetworkPtr net = CreateScatterNdNetwork(shapeInfo, indicesInfo, updatesInfo, outputInfo, + indicesData, updatesData, descriptor); + + CHECK(net); + + std::map> inputTensorData = {{ 0, shapeData }}; + std::map> expectedOutputData = {{ 0, expectedOutput }}; + + EndToEndLayerTestImpl(std::move(net), inputTensorData, expectedOutputData, backends); +} + +} // anonymous namespace diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp index 4af54852fc..73786b5ccd 100644 --- a/src/backends/reference/test/RefEndToEndTests.cpp +++ b/src/backends/reference/test/RefEndToEndTests.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -1339,6 +1340,49 @@ TEST_CASE("QuantizationEndToEndFloat16_S16Test") QuantizationEndToEndFloat16(defaultBackends); } +// ScatterNd + +TEST_CASE("RefScatterNd1DInputEndToEndFloat32Test") +{ + ScatterNd1DimUpdateWithInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd1DInputEndToEndInt8Test") +{ + ScatterNd1DimUpdateWithInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd1DNoInputEndToEndFloat32Test") +{ + ScatterNd1DimUpdateNoInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd1DNoInputEndToEndInt8Test") +{ + ScatterNd1DimUpdateNoInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd2DInputEndToEndFloat32Test") +{ + ScatterNd2DimUpdateWithInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd2DInputEndToEndInt8Test") +{ + ScatterNd2DimUpdateWithInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd2DNoInputEndToEndFloat32Test") +{ + ScatterNd2DimUpdateNoInputEndToEnd(defaultBackends); +} + +TEST_CASE("RefScatterNd2DNoInputEndToEndInt8Test") +{ + ScatterNd2DimUpdateNoInputEndToEnd(defaultBackends); +} + + // SpaceToDepth TEST_CASE("RefSpaceToDepthNhwcEndToEndTest1") { -- cgit v1.2.1