blob: ec9e0631fec0b017b15f69d10caba1fbb5da39de [file] [log] [blame]
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "NeonTensorHandleFactory.hpp"
7#include "NeonTensorHandle.hpp"
8
Narumol Prangnawarat1a268962020-07-27 15:52:13 +01009#include "Layer.hpp"
10
Jan Eilers8eb25602020-03-09 12:13:48 +000011#include <armnn/utility/IgnoreUnused.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010012#include <armnn/utility/PolymorphicDowncast.hpp>
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010013
14namespace armnn
15{
16
Jan Eilerse9f0f0f2019-08-16 10:28:37 +010017using FactoryId = ITensorHandleFactory::FactoryId;
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010018
19std::unique_ptr<ITensorHandle> NeonTensorHandleFactory::CreateSubTensorHandle(ITensorHandle& parent,
Jan Eilerse9f0f0f2019-08-16 10:28:37 +010020 const TensorShape& subTensorShape,
21 const unsigned int* subTensorOrigin)
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010022 const
23{
24 const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
25
26 arm_compute::Coordinates coords;
27 coords.set_num_dimensions(subTensorShape.GetNumDimensions());
Jan Eilerse9f0f0f2019-08-16 10:28:37 +010028 for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); ++i)
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010029 {
30 // Arm compute indexes tensor coords in reverse order.
31 unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1;
32 coords.set(i, boost::numeric_cast<int>(subTensorOrigin[revertedIndex]));
33 }
34
35 const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape());
36 if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape))
37 {
38 return nullptr;
39 }
40
41 return std::make_unique<NeonSubTensorHandle>(
Jan Eilersbb446e52020-04-02 13:56:54 +010042 PolymorphicDowncast<IAclTensorHandle*>(&parent), shape, coords);
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010043}
44
David Monahanc6e5a6e2019-10-02 09:33:57 +010045std::unique_ptr<ITensorHandle> NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const
46{
47 return NeonTensorHandleFactory::CreateTensorHandle(tensorInfo, true);
48}
49
50std::unique_ptr<ITensorHandle> NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
51 DataLayout dataLayout) const
52{
53 return NeonTensorHandleFactory::CreateTensorHandle(tensorInfo, dataLayout, true);
54}
55
David Monahan3fb7e102019-08-20 11:25:29 +010056std::unique_ptr<ITensorHandle> NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
57 const bool IsMemoryManaged) const
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010058{
59 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
David Monahan3fb7e102019-08-20 11:25:29 +010060 if (IsMemoryManaged)
61 {
62 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
63 }
64 // If we are not Managing the Memory then we must be importing
65 tensorHandle->SetImportEnabledFlag(!IsMemoryManaged);
James Conroy57d10b72019-10-25 09:44:14 +010066 tensorHandle->SetImportFlags(GetImportFlags());
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010067
68 return tensorHandle;
69}
70
71std::unique_ptr<ITensorHandle> NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
David Monahan3fb7e102019-08-20 11:25:29 +010072 DataLayout dataLayout,
73 const bool IsMemoryManaged) const
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010074{
75 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
David Monahan3fb7e102019-08-20 11:25:29 +010076 if (IsMemoryManaged)
77 {
78 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
79 }
80 // If we are not Managing the Memory then we must be importing
81 tensorHandle->SetImportEnabledFlag(!IsMemoryManaged);
James Conroy57d10b72019-10-25 09:44:14 +010082 tensorHandle->SetImportFlags(GetImportFlags());
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010083
84 return tensorHandle;
85}
86
Jan Eilerse9f0f0f2019-08-16 10:28:37 +010087const FactoryId& NeonTensorHandleFactory::GetIdStatic()
88{
89 static const FactoryId s_Id(NeonTensorHandleFactoryId());
90 return s_Id;
91}
92
Ferran Balaguerbfeb2712019-08-07 15:14:56 +010093const FactoryId& NeonTensorHandleFactory::GetId() const
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010094{
Jan Eilerse9f0f0f2019-08-16 10:28:37 +010095 return GetIdStatic();
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +010096}
97
98bool NeonTensorHandleFactory::SupportsSubTensors() const
99{
100 return true;
101}
102
103MemorySourceFlags NeonTensorHandleFactory::GetExportFlags() const
104{
James Conroy57d10b72019-10-25 09:44:14 +0100105 return 0;
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +0100106}
107
108MemorySourceFlags NeonTensorHandleFactory::GetImportFlags() const
109{
James Conroyffab16f2019-11-07 14:37:09 +0000110 return 0;
Narumol Prangnawarat4e3e8182019-08-14 12:25:50 +0100111}
112
Narumol Prangnawarat1a268962020-07-27 15:52:13 +0100113std::vector<Capability> NeonTensorHandleFactory::GetCapabilities(const IConnectableLayer* layer,
114 const IConnectableLayer* connectedLayer,
115 CapabilityClass capabilityClass)
116
117{
118 IgnoreUnused(connectedLayer);
119 std::vector<Capability> capabilities;
120 if (capabilityClass == CapabilityClass::PaddingRequired)
121 {
122 auto search = paddingRequiredLayers.find((PolymorphicDowncast<const Layer*>(layer))->GetType());
123 if ( search != paddingRequiredLayers.end())
124 {
125 Capability paddingCapability(CapabilityClass::PaddingRequired, true);
126 capabilities.push_back(paddingCapability);
127 }
128 }
129 return capabilities;
130}
131
Ferran Balaguerbfeb2712019-08-07 15:14:56 +0100132} // namespace armnn