diff options
Diffstat (limited to 'src/backends/reference/workloads')
6 files changed, 237 insertions, 0 deletions
diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index 3592f2293d..28f6d2f371 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -66,6 +66,8 @@ list(APPEND armnnRefBackendWorkloads_sources PreluImpl.hpp Reduce.cpp Reduce.hpp + ReverseV2Impl.cpp + ReverseV2Impl.hpp RefActivationWorkload.cpp RefActivationWorkload.hpp RefArgMinMaxWorkload.cpp @@ -161,6 +163,8 @@ list(APPEND armnnRefBackendWorkloads_sources RefReshapeWorkload.hpp RefResizeWorkload.cpp RefResizeWorkload.hpp + RefReverseV2Workload.cpp + RefReverseV2Workload.hpp RefShapeWorkload.hpp RefSliceWorkload.cpp RefSliceWorkload.hpp diff --git a/src/backends/reference/workloads/RefReverseV2Workload.cpp b/src/backends/reference/workloads/RefReverseV2Workload.cpp new file mode 100644 index 0000000000..cd2d9f930b --- /dev/null +++ b/src/backends/reference/workloads/RefReverseV2Workload.cpp @@ -0,0 +1,48 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefReverseV2Workload.hpp" + +#include "ReverseV2Impl.hpp" +#include "RefWorkloadUtils.hpp" +#include "Profiling.hpp" + +namespace armnn +{ + + RefReverseV2Workload::RefReverseV2Workload(const ReverseV2QueueDescriptor& descriptor, const WorkloadInfo& info) + : RefBaseWorkload(descriptor, info) + {} + + void RefReverseV2Workload::Execute() const + { + Execute(m_Data.m_Inputs, m_Data.m_Outputs); + } + + void RefReverseV2Workload::ExecuteAsync(ExecutionData& executionData) + { + WorkingMemDescriptor* workingMemDescriptor = static_cast<WorkingMemDescriptor*>(executionData.m_Data); + Execute(workingMemDescriptor->m_Inputs, workingMemDescriptor->m_Outputs); + } + + void RefReverseV2Workload::Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const + { + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefReverseV2Workload_Execute"); + + const TensorInfo& inputInfo = GetTensorInfo(inputs[0]); + + std::unique_ptr<Decoder<float>> inputDecoder = MakeDecoder<float>(GetTensorInfo(inputs[0]), + inputs[0]->Map()); + + std::unique_ptr<Encoder<float>> outputEncoder = MakeEncoder<float>(GetTensorInfo(outputs[0]), + outputs[0]->Map()); + + ReverseV2(m_Data.m_Parameters, + inputInfo, + *inputDecoder, + *outputEncoder); + } + +} // namespace armnn
\ No newline at end of file diff --git a/src/backends/reference/workloads/RefReverseV2Workload.hpp b/src/backends/reference/workloads/RefReverseV2Workload.hpp new file mode 100644 index 0000000000..89e7c9ea38 --- /dev/null +++ b/src/backends/reference/workloads/RefReverseV2Workload.hpp @@ -0,0 +1,30 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "RefBaseWorkload.hpp" +#include <armnn/backends/WorkloadData.hpp> + +#include "ReverseV2Impl.hpp" + +namespace armnn +{ + + class RefReverseV2Workload : public RefBaseWorkload<ReverseV2QueueDescriptor> + { + public: + explicit RefReverseV2Workload(const ReverseV2QueueDescriptor& descriptor, + const WorkloadInfo& info); + + void Execute() const override; + void ExecuteAsync(ExecutionData& executionData) override; + + private: + void Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const; + + }; + +} // namespace armnn
\ No newline at end of file diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index dba880bafc..e15a7ca047 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -53,6 +53,7 @@ #include "RefReduceWorkload.hpp" #include "RefReshapeWorkload.hpp" #include "RefResizeWorkload.hpp" +#include "RefReverseV2Workload.hpp" #include "RefShapeWorkload.hpp" #include "RefSliceWorkload.hpp" #include "RefSplitterWorkload.hpp" diff --git a/src/backends/reference/workloads/ReverseV2Impl.cpp b/src/backends/reference/workloads/ReverseV2Impl.cpp new file mode 100644 index 0000000000..f6d5fd74d1 --- /dev/null +++ b/src/backends/reference/workloads/ReverseV2Impl.cpp @@ -0,0 +1,133 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ReverseV2Impl.hpp" + +#include <armnn/backends/WorkloadData.hpp> +#include <armnn/Logging.hpp> +#include <armnnUtils/Permute.hpp> + +namespace armnn +{ + +// Get multi-dimensional index for input tensor +std::vector<unsigned int> ReverseGetMultIdx(const unsigned int idx, + unsigned int inputRank, + std::vector<unsigned int>& elementNumInner) +{ + std::vector<unsigned int> indexList(inputRank); + + unsigned int mIdx = idx; + + for (unsigned int iDim = 0; iDim < inputRank; ++iDim) + { + indexList[iDim] = static_cast<unsigned int>(mIdx / elementNumInner[iDim]); + mIdx %= elementNumInner[iDim]; + } + + return indexList; +} + +// Get flattened index for output encoder +unsigned int ReverseGetFlatIdx(const std::vector<unsigned int>& idxList, + unsigned int inputRank, + std::vector<unsigned int>& elementNumInner) +{ + unsigned int idx = 0; + + for (unsigned int iDim = 0; iDim < inputRank; ++iDim) + { + idx += idxList[iDim] * elementNumInner[iDim]; + } + + return idx; +} + +// Relocate the coordinate to the reversed tensor +unsigned int ReverseRelocateIdx(unsigned int idx, + unsigned int inputRank, + std::vector<bool>& axisFlag, + std::vector<unsigned int>& dimSize, + std::vector<unsigned int>& elementNumInner) +{ + // Get the multidimensional index list for input + auto inputIdxList = ReverseGetMultIdx(idx, inputRank, elementNumInner); + + std::vector<unsigned int> outputIdxList(inputRank); + + // Relocate the input index to the output one + for (unsigned int iDim = 0; iDim < inputRank; ++iDim) + { + if (axisFlag[iDim]) + { + outputIdxList[iDim] = dimSize[iDim] - inputIdxList[iDim] - 1; + } + else + { + outputIdxList[iDim] = inputIdxList[iDim]; + } + } + + // Get the 1-dimensional flattened index for output + unsigned int outputIdx = ReverseGetFlatIdx(outputIdxList, inputRank, elementNumInner); + return outputIdx; +} + +void ReverseV2(const ReverseV2Descriptor& params, + const TensorInfo& inputInfo, + Decoder<float>& inputDecoder, + Encoder<float>& outputEncoder) +{ + // Empty axis and empty tensor case: copy input to output + if (params.m_Axis.empty() || inputInfo.GetNumElements() == 0) + { + for (unsigned idx = 0; idx < inputInfo.GetNumElements(); idx++) + { + float inputValue = inputDecoder.Get(); + inputDecoder += 1; + outputEncoder.Set(inputValue); + outputEncoder += 1; + } + return; + } + + unsigned int inputRank = static_cast<unsigned int>(inputInfo.GetNumDimensions()); + + std::vector<bool>axisFlag(inputRank, false); + std::vector<unsigned int>dimSize(inputRank, 0); + + // Make sure the axes are positive + for (int32_t axisElement: params.m_Axis) + { + axisElement = axisElement < 0 ? axisElement + static_cast<int32_t>(inputRank) : axisElement; + axisFlag[static_cast<uint32_t>(axisElement)] = true; + } + + const TensorShape &inputShape = inputInfo.GetShape(); + + unsigned int elementNum = inputInfo.GetNumElements(); + unsigned int baseDimSize = 1; + + std::vector<unsigned int> elementNumInner; + + // Get the number of element within the specific dimension + for (unsigned int iDim = 0; iDim < inputRank; ++iDim) { + dimSize[iDim] = inputShape[iDim]; + baseDimSize *= dimSize[iDim]; + elementNumInner.push_back(static_cast<unsigned int>(elementNum / baseDimSize)); + } + + // Iterate through all elements + for (unsigned int idx = 0; idx < elementNum; ++idx) + { + float inputValue = inputDecoder.Get(); + inputDecoder += 1; + auto outputIdx = ReverseRelocateIdx(idx, inputRank, axisFlag, dimSize, elementNumInner); + outputEncoder[outputIdx]; + outputEncoder.Set(inputValue); + } +} + +} // namespace armnn
\ No newline at end of file diff --git a/src/backends/reference/workloads/ReverseV2Impl.hpp b/src/backends/reference/workloads/ReverseV2Impl.hpp new file mode 100644 index 0000000000..bc1fe1d432 --- /dev/null +++ b/src/backends/reference/workloads/ReverseV2Impl.hpp @@ -0,0 +1,21 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "Encoders.hpp" +#include "Decoders.hpp" + +#include <armnn/backends/WorkloadData.hpp> + +namespace armnn +{ + +void ReverseV2(const ReverseV2Descriptor& params, + const TensorInfo& inputInfo, + Decoder<float>& inputDecoder, + Encoder<float>& outputEncoder); + +} // namespace armnn
\ No newline at end of file |