From cbb66aa4b7ec93e9a64a1dec5ebc4158056ec061 Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Wed, 15 May 2019 13:03:54 +0100 Subject: IVGCVSW-2972 Support QSymm16 for Merger Change-Id: If2289b2d1fc20f4524fcf4620f01ea3a36d727d2 Signed-off-by: Jim Flynn --- src/backends/reference/RefLayerSupport.cpp | 26 +++++++++--- src/backends/reference/RefWorkloadFactory.cpp | 6 ++- src/backends/reference/backend.mk | 3 +- .../reference/test/RefCreateWorkloadTests.cpp | 25 ++++++----- src/backends/reference/test/RefLayerTests.cpp | 1 + src/backends/reference/workloads/CMakeLists.txt | 6 +-- src/backends/reference/workloads/Merger.cpp | 49 +++++----------------- src/backends/reference/workloads/Merger.hpp | 6 --- .../workloads/RefMergerFloat32Workload.cpp | 21 ---------- .../workloads/RefMergerFloat32Workload.hpp | 21 ---------- .../reference/workloads/RefMergerUint8Workload.cpp | 21 ---------- .../reference/workloads/RefMergerUint8Workload.hpp | 21 ---------- .../reference/workloads/RefMergerWorkload.cpp | 21 ++++++++++ .../reference/workloads/RefMergerWorkload.hpp | 21 ++++++++++ src/backends/reference/workloads/RefWorkloads.hpp | 3 +- 15 files changed, 99 insertions(+), 152 deletions(-) delete mode 100644 src/backends/reference/workloads/RefMergerFloat32Workload.cpp delete mode 100644 src/backends/reference/workloads/RefMergerFloat32Workload.hpp delete mode 100644 src/backends/reference/workloads/RefMergerUint8Workload.cpp delete mode 100644 src/backends/reference/workloads/RefMergerUint8Workload.hpp create mode 100644 src/backends/reference/workloads/RefMergerWorkload.cpp create mode 100644 src/backends/reference/workloads/RefMergerWorkload.hpp (limited to 'src/backends/reference') diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp index f79c152139..858bd878ae 100644 --- a/src/backends/reference/RefLayerSupport.cpp +++ b/src/backends/reference/RefLayerSupport.cpp @@ -729,11 +729,27 @@ bool RefLayerSupport::IsMergerSupported(const std::vector inp Optional reasonIfUnsupported) const { ignore_unused(descriptor); - ignore_unused(output); - return IsSupportedForDataTypeRef(reasonIfUnsupported, - inputs[0]->GetDataType(), - &TrueFunc<>, - &TrueFunc<>); + + bool supported = true; + std::array supportedTypes = + { + DataType::Float32, + DataType::QuantisedAsymm8, + DataType::QuantisedSymm16 + }; + + supported &= CheckSupportRule(TypeAnyOf(output, supportedTypes), reasonIfUnsupported, + "Reference concatenation: output type not supported"); + for (const TensorInfo* input : inputs) + { + supported &= CheckSupportRule(TypeAnyOf(*input, supportedTypes), reasonIfUnsupported, + "Reference concatenation: input type not supported"); + + supported &= CheckSupportRule(TypesAreEqual(*input, output), reasonIfUnsupported, + "Reference concatenation: input and output types mismatched."); + } + + return supported; } bool RefLayerSupport::IsMemCopySupported(const TensorInfo &input, diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp index 6603aaf27b..5c90a43c37 100644 --- a/src/backends/reference/RefWorkloadFactory.cpp +++ b/src/backends/reference/RefWorkloadFactory.cpp @@ -135,7 +135,11 @@ std::unique_ptr RefWorkloadFactory::CreateSplitter(const SplitterQueu std::unique_ptr RefWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor, const WorkloadInfo& info) const { - return MakeWorkload(descriptor, info); + if (IsFloat16(info)) + { + return MakeWorkload(descriptor, info); + } + return std::make_unique(descriptor, info); } std::unique_ptr RefWorkloadFactory::CreateFullyConnected( diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk index 5034c0fe9e..a297529d60 100644 --- a/src/backends/reference/backend.mk +++ b/src/backends/reference/backend.mk @@ -50,8 +50,7 @@ BACKEND_SOURCES := \ workloads/RefLstmWorkload.cpp \ workloads/RefMeanFloat32Workload.cpp \ workloads/RefMeanUint8Workload.cpp \ - workloads/RefMergerFloat32Workload.cpp \ - workloads/RefMergerUint8Workload.cpp \ + workloads/RefMergerWorkload.cpp \ workloads/RefNormalizationFloat32Workload.cpp \ workloads/RefPadWorkload.cpp \ workloads/RefPermuteWorkload.cpp \ diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp index 5da1f94f6e..788b6559f6 100644 --- a/src/backends/reference/test/RefCreateWorkloadTests.cpp +++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp @@ -479,12 +479,12 @@ static void RefCreateSplitterMergerWorkloadTest() BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloat32) { - RefCreateSplitterMergerWorkloadTest(); + RefCreateSplitterMergerWorkloadTest(); } BOOST_AUTO_TEST_CASE(CreateSplitterMergerUint8) { - RefCreateSplitterMergerWorkloadTest(); + RefCreateSplitterMergerWorkloadTest(); } template @@ -658,42 +658,47 @@ static void RefCreateMergerWorkloadTest(const armnn::TensorShape& outputShape, BOOST_AUTO_TEST_CASE(CreateMergerDim0Float32Workload) { - RefCreateMergerWorkloadTest({ 4, 3, 2, 5 }, 0); + RefCreateMergerWorkloadTest({ 4, 3, 2, 5 }, 0); } BOOST_AUTO_TEST_CASE(CreateMergerDim0Uint8Workload) { - RefCreateMergerWorkloadTest({ 4, 3, 2, 5 }, 0); + RefCreateMergerWorkloadTest({ 4, 3, 2, 5 }, 0); +} + +BOOST_AUTO_TEST_CASE(CreateMergerDim0Uint16Workload) +{ + RefCreateMergerWorkloadTest({ 4, 3, 2, 5 }, 0); } BOOST_AUTO_TEST_CASE(CreateMergerDim1Float32Workload) { - RefCreateMergerWorkloadTest({ 2, 6, 2, 5 }, 1); + RefCreateMergerWorkloadTest({ 2, 6, 2, 5 }, 1); } BOOST_AUTO_TEST_CASE(CreateMergerDim1Uint8Workload) { - RefCreateMergerWorkloadTest({ 2, 6, 2, 5 }, 1); + RefCreateMergerWorkloadTest({ 2, 6, 2, 5 }, 1); } BOOST_AUTO_TEST_CASE(CreateMergerDim2Float32Workload) { - RefCreateMergerWorkloadTest({ 2, 3, 4, 5 }, 2); + RefCreateMergerWorkloadTest({ 2, 3, 4, 5 }, 2); } BOOST_AUTO_TEST_CASE(CreateMergerDim2Uint8Workload) { - RefCreateMergerWorkloadTest({ 2, 3, 4, 5 }, 2); + RefCreateMergerWorkloadTest({ 2, 3, 4, 5 }, 2); } BOOST_AUTO_TEST_CASE(CreateMergerDim3Float32Workload) { - RefCreateMergerWorkloadTest({ 2, 3, 2, 10 }, 3); + RefCreateMergerWorkloadTest({ 2, 3, 2, 10 }, 3); } BOOST_AUTO_TEST_CASE(CreateMergerDim3Uint8Workload) { - RefCreateMergerWorkloadTest({ 2, 3, 2, 10 }, 3); + RefCreateMergerWorkloadTest({ 2, 3, 2, 10 }, 3); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index 01afff8b02..053de9e14f 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -246,6 +246,7 @@ ARMNN_AUTO_TEST_CASE(CopyViaSplitterUint8, CopyViaSplitterUint8Test) ARMNN_AUTO_TEST_CASE(SimpleMerger, MergerTest) ARMNN_AUTO_TEST_CASE(MergerUint8, MergerUint8Test) ARMNN_AUTO_TEST_CASE(MergerUint8DifferentQParams, MergerUint8DifferentQParamsTest) +ARMNN_AUTO_TEST_CASE(MergerUint16, MergerUint16Test) // Add ARMNN_AUTO_TEST_CASE(SimpleAdd, AdditionTest) diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index b1cdef9cf1..8c8aa6ffb5 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -83,10 +83,8 @@ list(APPEND armnnRefBackendWorkloads_sources RefL2NormalizationFloat32Workload.hpp RefLstmWorkload.cpp RefLstmWorkload.hpp - RefMergerFloat32Workload.cpp - RefMergerFloat32Workload.hpp - RefMergerUint8Workload.cpp - RefMergerUint8Workload.hpp + RefMergerWorkload.cpp + RefMergerWorkload.hpp RefNormalizationFloat32Workload.cpp RefNormalizationFloat32Workload.hpp RefPadWorkload.cpp diff --git a/src/backends/reference/workloads/Merger.cpp b/src/backends/reference/workloads/Merger.cpp index 8877ee2284..e0b70ee5cb 100644 --- a/src/backends/reference/workloads/Merger.cpp +++ b/src/backends/reference/workloads/Merger.cpp @@ -5,43 +5,19 @@ #include "Merger.hpp" #include "RefWorkloadUtils.hpp" +#include "Decoders.hpp" +#include "Encoders.hpp" namespace armnn { -template <> -void CopyValue(const float& source, const TensorInfo& sourceInfo, float& dest, const TensorInfo& destInfo) -{ - dest = source; -} - -template <> -void CopyValue(const uint8_t& source, const TensorInfo& sourceInfo, uint8_t& dest, const TensorInfo& destInfo) -{ - if (sourceInfo.GetQuantizationScale() != destInfo.GetQuantizationScale() || - sourceInfo.GetQuantizationOffset() != destInfo.GetQuantizationOffset()) - { - // Dequantize value according to sourceInfo params - float dequantizedValue = armnn::Dequantize(source, - sourceInfo.GetQuantizationScale(), - sourceInfo.GetQuantizationOffset()); - - // Quantize again according to destInfo paramns - dest = armnn::Quantize(dequantizedValue, - destInfo.GetQuantizationScale(), - destInfo.GetQuantizationOffset()); - } - else - { - dest = source; - } -} - -template void Merger(const MergerQueueDescriptor& data) { const TensorInfo& outputInfo0 = GetTensorInfo(data.m_Outputs[0]); + std::unique_ptr> encoderPtr = MakeEncoder(outputInfo0, data.m_Outputs[0]->Map()); + Encoder& encoder = *encoderPtr; + for (unsigned int index = 0 ; index < outputInfo0.GetNumElements(); ++index) { unsigned int indices[MaxNumOfTensorDimensions] = { 0 }; @@ -80,6 +56,9 @@ void Merger(const MergerQueueDescriptor& data) if (insideView) { + std::unique_ptr> decoderPtr = + MakeDecoder(inputInfo, data.m_Inputs[viewIdx]->Map()); + Decoder& decoder = *decoderPtr; unsigned int inIndex = 0; unsigned int dimensionStride = 1; @@ -88,11 +67,8 @@ void Merger(const MergerQueueDescriptor& data) inIndex += dimensionStride * (indices[i] - view.m_Origin[i]); dimensionStride *= inputInfo.GetShape()[i]; } - - CopyValue((GetInputTensorData(viewIdx, data))[inIndex], - GetTensorInfo(data.m_Inputs[viewIdx]), - (GetOutputTensorData(0, data))[index], - outputInfo0); + decoder += inIndex; + encoder.Set(decoder.Get()); //What should we do if input views overlap on the output tensor? //We could error, take the average, or shm else... @@ -100,11 +76,8 @@ void Merger(const MergerQueueDescriptor& data) break; } } + ++encoder; } } -template void Merger(const MergerQueueDescriptor& data); - -template void Merger(const MergerQueueDescriptor& data); - } //namespace armnn diff --git a/src/backends/reference/workloads/Merger.hpp b/src/backends/reference/workloads/Merger.hpp index ba3b99b6e2..eaa154d25a 100644 --- a/src/backends/reference/workloads/Merger.hpp +++ b/src/backends/reference/workloads/Merger.hpp @@ -10,11 +10,5 @@ namespace armnn { - -template -void CopyValue(const DataType& source, const TensorInfo& sourceInfo, DataType& dest, const TensorInfo& destInfo); - -template void Merger(const MergerQueueDescriptor& data); - } //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerFloat32Workload.cpp b/src/backends/reference/workloads/RefMergerFloat32Workload.cpp deleted file mode 100644 index b1f8a32ee7..0000000000 --- a/src/backends/reference/workloads/RefMergerFloat32Workload.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "RefMergerFloat32Workload.hpp" - -#include "Merger.hpp" - -#include "Profiling.hpp" - -namespace armnn -{ - -void RefMergerFloat32Workload::Execute() const -{ - ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefMergerFloat32Workload_Execute"); - Merger(m_Data); -} - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerFloat32Workload.hpp b/src/backends/reference/workloads/RefMergerFloat32Workload.hpp deleted file mode 100644 index 8d7b2706f3..0000000000 --- a/src/backends/reference/workloads/RefMergerFloat32Workload.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -namespace armnn -{ - -class RefMergerFloat32Workload : public Float32Workload -{ -public: - using Float32Workload::Float32Workload; - virtual void Execute() const override; -}; - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerUint8Workload.cpp b/src/backends/reference/workloads/RefMergerUint8Workload.cpp deleted file mode 100644 index 47ce1cf731..0000000000 --- a/src/backends/reference/workloads/RefMergerUint8Workload.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "RefMergerUint8Workload.hpp" - -#include "Merger.hpp" - -#include "Profiling.hpp" - -namespace armnn -{ - -void RefMergerUint8Workload::Execute() const -{ - ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefMergerUint8Workload_Execute"); - Merger(m_Data); -} - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerUint8Workload.hpp b/src/backends/reference/workloads/RefMergerUint8Workload.hpp deleted file mode 100644 index df23af093f..0000000000 --- a/src/backends/reference/workloads/RefMergerUint8Workload.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -namespace armnn -{ - -class RefMergerUint8Workload : public Uint8Workload -{ -public: - using Uint8Workload::Uint8Workload; - virtual void Execute() const override; -}; - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerWorkload.cpp b/src/backends/reference/workloads/RefMergerWorkload.cpp new file mode 100644 index 0000000000..5b42e828b9 --- /dev/null +++ b/src/backends/reference/workloads/RefMergerWorkload.cpp @@ -0,0 +1,21 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefMergerWorkload.hpp" + +#include "Merger.hpp" + +#include "Profiling.hpp" + +namespace armnn +{ + +void RefMergerWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefMergerWorkload_Execute"); + Merger(m_Data); +} + +} //namespace armnn diff --git a/src/backends/reference/workloads/RefMergerWorkload.hpp b/src/backends/reference/workloads/RefMergerWorkload.hpp new file mode 100644 index 0000000000..138838a1af --- /dev/null +++ b/src/backends/reference/workloads/RefMergerWorkload.hpp @@ -0,0 +1,21 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +namespace armnn +{ + +class RefMergerWorkload : public BaseWorkload +{ +public: + using BaseWorkload::BaseWorkload; + virtual void Execute() const override; +}; + +} //namespace armnn diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index 8ffd3485ae..9a2eb0a8af 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -16,11 +16,10 @@ #include "RefActivationWorkload.hpp" #include "RefPooling2dFloat32Workload.hpp" #include "RefWorkloadUtils.hpp" -#include "RefMergerUint8Workload.hpp" +#include "RefMergerWorkload.hpp" #include "RefFullyConnectedFloat32Workload.hpp" #include "RefGatherWorkload.hpp" #include "Softmax.hpp" -#include "RefMergerFloat32Workload.hpp" #include "TensorBufferArrayView.hpp" #include "RefBatchNormalizationFloat32Workload.hpp" #include "Splitter.hpp" -- cgit v1.2.1