blob: db02a84a4561cb4433cfc021db45b905bf50f42b [file] [log] [blame]
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8#include "BaseIterator.hpp"
9#include <backendsCommon/CpuTensorHandle.hpp>
10
11namespace
12{
13
14// Helper functions ported from the Android code base
15// Refer to: android/external/tensorflow/tensorflow/contrib/lite/kernels/internal/reference/portable_tensor_utils.cc
16
17void MatrixBatchVectorMultiplyAccumulate(armnn::Decoder<float>& matrix,
18 uint32_t mRows,
19 uint32_t mCols,
20 armnn::Decoder<float>& vector,
21 uint32_t nBatch,
22 armnn::Encoder<float>& outResult)
23{
24 for (uint32_t b = 0; b < nBatch; b++)
25 {
26 for (uint32_t r = 0; r < mRows; r++)
27 {
28 vector += b * mCols;
29 for (uint32_t c = 0; c < mCols; c++)
30 {
31 outResult.Set(outResult.Get() + matrix.Get() * vector.Get());
32 ++matrix;
33 ++vector;
34 }
35 outResult += 1;
36 vector -= (b+1) * mCols;
37 }
38 matrix -= (mRows * mCols);
39 }
40 outResult -= (mRows * nBatch);
41}
42
43void VectorBatchVectorAssign(armnn::Decoder<float>& vector,
44 uint32_t vSize,
45 uint32_t nBatch,
46 armnn::Encoder<float>& outBatchVector)
47{
48 for (uint32_t b = 0; b < nBatch; b++)
49 {
50 for (uint32_t v = 0; v < vSize; v++)
51 {
52 outBatchVector.Set(vector.Get());
53 ++outBatchVector;
54 ++vector;
55 }
56 vector -= vSize;
57 }
58 outBatchVector -= (nBatch * vSize);
59}
60
61void VectorBatchVectorCwiseProductAccumulate(armnn::Decoder<float>& vector,
62 uint32_t vSize,
63 armnn::Decoder<float>& batchVector,
64 uint32_t nBatch,
65 armnn::Encoder<float>& outResult)
66{
67 for (uint32_t b = 0; b < nBatch; b++)
68 {
69 for (uint32_t v = 0; v < vSize; v++)
70 {
71 outResult.Set(outResult.Get() + vector.Get() * batchVector.Get());
72 ++outResult;
73 ++vector;
74 ++batchVector;
75 }
76 vector -= vSize;
77 }
78 batchVector -= vSize * nBatch;
79 outResult -= vSize * nBatch;
80}
81
82void Sub1Vector(armnn::Decoder<float>& vector,
83 uint32_t vSize,
84 armnn::Encoder<float>& result)
85{
86 for (uint32_t v = 0; v < vSize; v++)
87 {
88 result.Set(1.0f - vector.Get());
89 ++vector;
90 ++result;
91 }
92 vector -= vSize;
93 result -= vSize;
94}
95
96void VectorVectorCwiseProduct(armnn::Decoder<float>& vector1,
97 armnn::Decoder<float>& vector2,
98 uint32_t vSize,
99 armnn::Encoder<float>& outResult)
100{
101 for (uint32_t v = 0; v < vSize; v++)
102 {
103 outResult.Set(vector1.Get() * vector2.Get());
104 ++outResult;
105 ++vector1;
106 ++vector2;
107 }
108 outResult -= vSize;
109 vector1 -= vSize;
110 vector2 -= vSize;
111}
112
113void VectorVectorCwiseProductAccumulate(armnn::Decoder<float>& vector1,
114 armnn::Decoder<float>& vector2,
115 uint32_t vSize,
116 armnn::Encoder<float>& outResult)
117{
118 for (uint32_t v = 0; v < vSize; v++)
119 {
120 outResult.Set(outResult.Get() + vector1.Get() * vector2.Get());
121 ++outResult;
122 ++vector1;
123 ++vector2;
124 }
125 outResult -= vSize;
126 vector1 -= vSize;
127 vector2 -= vSize;
128}
129
130float Clip(float f,
131 float absLimit)
132{
133 float result = (absLimit < f) ? absLimit : f;
134 result = (-absLimit > result) ? -absLimit : result;
135 return result;
136}
137
138void ClipVector(armnn::Decoder<float>& vector,
139 uint32_t vSize,
140 float absLimit,
141 armnn::Encoder<float>& outResult)
142{
143 for (uint32_t v = 0; v < vSize; v++)
144 {
145 outResult.Set(Clip(vector.Get(), absLimit));
146 ++vector;
147 ++outResult;
148 }
149 vector -= vSize;
150 outResult -= vSize;
151}
152
153void CopyVector(armnn::Decoder<float>& vector,
154 uint32_t vSize,
155 armnn::Encoder<float>& outResult)
156{
157 for (uint32_t v = 0; v < vSize; v++)
158 {
159 outResult.Set(vector.Get());
160 ++outResult;
161 ++vector;
162 }
163 outResult -= vSize;
164 vector -= vSize;
165}
166
167void SetActivationParameters(uint32_t activation,
168 armnn::ActivationFunction& outArmnnActivation,
169 float& outA,
170 float& outB)
171{
172 switch (activation)
173 {
174 case 0: // None
175 outA = 0;
176 outB = 0;
177 return;
178
179 case 1: // Relu
180 outArmnnActivation = armnn::ActivationFunction::ReLu;
181 outA = 0;
182 outB = 0;
183 return;
184
185 case 3: // Relu6
186 outArmnnActivation = armnn::ActivationFunction::BoundedReLu;
187 outA = 6;
188 outB = 0;
189 return;
190
191 case 4: // Tanh
192 outArmnnActivation = armnn::ActivationFunction::TanH;
193 outA = 1;
194 outB = 1;
195 return;
196
197 case 6: // Sigmoid
198 outArmnnActivation = armnn::ActivationFunction::Sigmoid;
199 outA = 0;
200 outB = 0;
201 return;
202
203 default:
204 throw armnn::Exception("Unsupported activation function: " + std::to_string(activation));
205 }
206}
207
208std::unique_ptr<armnn::ScopedCpuTensorHandle> AssignScopedCpuTensorHandle(const armnn::ConstCpuTensorHandle* ptr)
209{
210 if (!ptr)
211 {
212 return nullptr;
213 }
214
215 return std::make_unique<armnn::ScopedCpuTensorHandle>(*ptr);
216}
217
218} // anonymous namespace