blob: de743088da3075e91d27b4de4191bc3d16b9a457 [file] [log] [blame]
arovir01b0717b52018-09-05 17:03:25 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "HalPolicy.hpp"
7
8#include "../1.0/HalPolicy.hpp"
9
10namespace armnn_driver
11{
12namespace hal_1_1
13{
14
15bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model, ConversionData& data)
16{
17 if (compliantWithV1_0(operation))
18 {
19 hal_1_0::HalPolicy::Operation v10Operation = convertToV1_0(operation);
20 hal_1_0::HalPolicy::Model v10Model = convertToV1_0(model);
21
22 return hal_1_0::HalPolicy::ConvertOperation(v10Operation, v10Model, data);
23 }
24 else
25 {
26 switch (operation.type)
27 {
28 case V1_1::OperationType::DIV:
29 return ConvertDiv(operation, model, data);
David Beck38e12942018-09-12 16:02:24 +010030 case V1_1::OperationType::SUB:
31 return ConvertSub(operation, model, data);
narpra013c052562018-09-17 14:25:04 +010032 case V1_1::OperationType::MEAN:
33 return ConvertMean(operation, model, data);
arovir01b0717b52018-09-05 17:03:25 +010034 default:
35 return Fail("%s: Operation type %s not supported in ArmnnDriver",
36 __func__, toString(operation.type).c_str());
37 }
38 }
39}
40
41bool HalPolicy::ConvertDiv(const Operation& operation, const Model& model, ConversionData& data)
42{
43 LayerInputHandle input0 = ConvertToLayerInputHandle(operation, 0, model, data);
44 LayerInputHandle input1 = ConvertToLayerInputHandle(operation, 1, model, data);
45
46 if (!input0.IsValid() || !input1.IsValid())
47 {
48 return Fail("%s: Operation has invalid inputs", __func__);
49 }
50
51 // The FuseActivation parameter is always the input index 2
52 // and it should be optional
53 ActivationFn activationFunction;
54 if (!GetOptionalInputActivation(operation, 2, activationFunction, model, data))
55 {
56 return Fail("%s: Operation has invalid inputs", __func__);
57 }
58
59 const Operand* outputOperand = GetOutputOperand(operation, 0, model);
60 if (!outputOperand)
61 {
62 return false;
63 }
64
65 const armnn::TensorInfo& outInfo = GetTensorInfoForOperand(*outputOperand);
66
67 if (!IsLayerSupported(__func__,
68 armnn::IsDivisionSupported,
69 data.m_Compute,
70 input0.GetTensorInfo(),
71 input1.GetTensorInfo(),
72 outInfo))
73 {
74 return false;
75 }
76
77 armnn::IConnectableLayer* const startLayer = data.m_Network->AddDivisionLayer();
78 armnn::IConnectableLayer* const endLayer = ProcessActivation(outInfo, activationFunction, startLayer, data);
79
80 const armnn::TensorInfo& inputTensorInfo0 = input0.GetTensorInfo();
81 const armnn::TensorInfo& inputTensorInfo1 = input1.GetTensorInfo();
82
83 if (endLayer)
84 {
85 BroadcastTensor(input0, input1, startLayer, *data.m_Network);
86 return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data);
87 }
88
89 return Fail("%s: ProcessActivation failed", __func__);
90}
91
David Beck38e12942018-09-12 16:02:24 +010092bool HalPolicy::ConvertSub(const Operation& operation, const Model& model, ConversionData& data)
93{
94 LayerInputHandle input0 = ConvertToLayerInputHandle(operation, 0, model, data);
95 LayerInputHandle input1 = ConvertToLayerInputHandle(operation, 1, model, data);
96
97 if (!input0.IsValid() || !input1.IsValid())
98 {
99 return Fail("%s: Operation has invalid inputs", __func__);
100 }
101
102 // The FuseActivation parameter is always the input index 2
103 // and it should be optional
104 ActivationFn activationFunction;
105 if (!GetOptionalInputActivation(operation, 2, activationFunction, model, data))
106 {
107 return Fail("%s: Operation has invalid inputs", __func__);
108 }
109
110 const Operand* outputOperand = GetOutputOperand(operation, 0, model);
111 if (!outputOperand)
112 {
113 return false;
114 }
115
116 const armnn::TensorInfo& outInfo = GetTensorInfoForOperand(*outputOperand);
117
118 if (!IsLayerSupported(__func__,
119 armnn::IsSubtractionSupported,
120 data.m_Compute,
121 input0.GetTensorInfo(),
122 input1.GetTensorInfo(),
123 outInfo))
124 {
125 return false;
126 }
127
128 armnn::IConnectableLayer* const startLayer = data.m_Network->AddSubtractionLayer();
129 armnn::IConnectableLayer* const endLayer = ProcessActivation(outInfo, activationFunction, startLayer, data);
130
131 const armnn::TensorInfo& inputTensorInfo0 = input0.GetTensorInfo();
132 const armnn::TensorInfo& inputTensorInfo1 = input1.GetTensorInfo();
133
134 if (endLayer)
135 {
136 BroadcastTensor(input0, input1, startLayer, *data.m_Network);
137 return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data);
138 }
139
140 return Fail("%s: ProcessActivation failed", __func__);
141}
142
narpra013c052562018-09-17 14:25:04 +0100143bool HalPolicy::ConvertMean(const Operation& operation, const Model& model, ConversionData& data)
144{
145 LayerInputHandle input = ConvertToLayerInputHandle(operation, 0, model, data);
146
147 if (!input.IsValid())
148 {
149 return Fail("%s: Operation has invalid inputs", __func__);
150 }
151
152 const armnn::TensorInfo& inputInfo = input.GetTensorInfo();
153
154 armnn::MeanDescriptor descriptor;
155
156 const Operand* axisOperand = GetInputOperand(operation, 1, model);
157 if (axisOperand)
158 {
159 std::vector<int32_t> axis;
160 GetTensorInt32Values(*axisOperand, axis, model, data);
161 unsigned int rank = inputInfo.GetNumDimensions();
162 // convert the axis to unsigned int.
163 for (auto& i : axis)
164 {
165 unsigned int unsignedAxis = (i + rank) % rank;
166 if (std::find(descriptor.m_Axis.begin(), descriptor.m_Axis.end(), unsignedAxis) == descriptor.m_Axis.end())
167 {
168 descriptor.m_Axis.push_back(unsignedAxis);
169 }
170 }
171 }
172
173 int32_t keepDims;
174 GetInputInt32(operation, 2, keepDims, model, data);
175 if (keepDims > 0)
176 {
177 descriptor.m_KeepDims = true;
178 }
179
180 const Operand* output = GetOutputOperand(operation, 0, model);
181 if (!output)
182 {
183 return Fail("%s: Could not read output 0", __func__);
184 }
185
186 const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output);
187
188 if (!IsLayerSupported(__func__,
189 armnn::IsMeanSupported,
190 data.m_Compute,
191 inputInfo,
192 outputInfo,
193 descriptor))
194 {
195 return false;
196 }
197
198 armnn::IConnectableLayer* const layer = data.m_Network->AddMeanLayer(descriptor);
narpra0196bedf02018-09-26 16:57:28 +0100199 assert(layer != nullptr);
200 input.Connect(layer->GetInputSlot(0));
201 layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
narpra013c052562018-09-17 14:25:04 +0100202
203 return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data);
204}
205
arovir01b0717b52018-09-05 17:03:25 +0100206} // namespace hal_1_1
207} // namespace armnn_driver