blob: 303676043e0037ca6251e367ac5b178e97c24736 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
Colm Donelanb4ef1632024-02-01 15:00:43 +00002// Copyright © 2017-2024 Arm Ltd and Contributors. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
Mike Kelly4cc341c2023-07-07 15:43:06 +01005
telsoa014fcda012018-03-09 14:13:49 +00006#pragma once
7
Narumol Prangnawarat250d3922020-03-30 16:11:04 +01008#include <BFloat16.hpp>
Aron Virginas-Tar99836d32019-09-30 16:34:31 +01009#include <Half.hpp>
10
Derek Lambertic81855f2019-06-13 17:34:19 +010011#include <aclCommon/ArmComputeTensorHandle.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <aclCommon/ArmComputeTensorUtils.hpp>
Colm Donelanb4ef1632024-02-01 15:00:43 +000013#include <armnn/Exceptions.hpp>
Jan Eilers3c9e0452020-04-10 13:00:44 +010014#include <armnn/utility/PolymorphicDowncast.hpp>
telsoa014fcda012018-03-09 14:13:49 +000015
telsoa01c577f2c2018-08-31 09:22:23 +010016#include <arm_compute/runtime/MemoryGroup.h>
17#include <arm_compute/runtime/IMemoryGroup.h>
telsoa014fcda012018-03-09 14:13:49 +000018#include <arm_compute/runtime/Tensor.h>
19#include <arm_compute/runtime/SubTensor.h>
20#include <arm_compute/core/TensorShape.h>
21#include <arm_compute/core/Coordinates.h>
Mike Kelly4cc341c2023-07-07 15:43:06 +010022#include "armnn/TypesUtils.hpp"
telsoa014fcda012018-03-09 14:13:49 +000023
telsoa014fcda012018-03-09 14:13:49 +000024namespace armnn
25{
Mike Kelly4cc341c2023-07-07 15:43:06 +010026class NeonTensorHandleDecorator;
telsoa014fcda012018-03-09 14:13:49 +000027
Derek Lambertic81855f2019-06-13 17:34:19 +010028class NeonTensorHandle : public IAclTensorHandle
telsoa014fcda012018-03-09 14:13:49 +000029{
30public:
31 NeonTensorHandle(const TensorInfo& tensorInfo)
David Monahan3fb7e102019-08-20 11:25:29 +010032 : m_ImportFlags(static_cast<MemorySourceFlags>(MemorySource::Malloc)),
33 m_Imported(false),
Finn Williamsb1aad422021-10-28 19:07:32 +010034 m_IsImportEnabled(false),
35 m_TypeAlignment(GetDataTypeSize(tensorInfo.GetDataType()))
telsoa014fcda012018-03-09 14:13:49 +000036 {
37 armnn::armcomputetensorutils::BuildArmComputeTensor(m_Tensor, tensorInfo);
38 }
39
David Monahan3fb7e102019-08-20 11:25:29 +010040 NeonTensorHandle(const TensorInfo& tensorInfo,
41 DataLayout dataLayout,
42 MemorySourceFlags importFlags = static_cast<MemorySourceFlags>(MemorySource::Malloc))
43 : m_ImportFlags(importFlags),
44 m_Imported(false),
Finn Williamsb1aad422021-10-28 19:07:32 +010045 m_IsImportEnabled(false),
46 m_TypeAlignment(GetDataTypeSize(tensorInfo.GetDataType()))
47
David Monahan3fb7e102019-08-20 11:25:29 +010048
Francis Murtagh351d13d2018-09-24 15:01:18 +010049 {
50 armnn::armcomputetensorutils::BuildArmComputeTensor(m_Tensor, tensorInfo, dataLayout);
51 }
52
telsoa014fcda012018-03-09 14:13:49 +000053 arm_compute::ITensor& GetTensor() override { return m_Tensor; }
54 arm_compute::ITensor const& GetTensor() const override { return m_Tensor; }
telsoa01c577f2c2018-08-31 09:22:23 +010055
telsoa014fcda012018-03-09 14:13:49 +000056 virtual void Allocate() override
57 {
David Monahan3fb7e102019-08-20 11:25:29 +010058 // If we have enabled Importing, don't Allocate the tensor
59 if (!m_IsImportEnabled)
60 {
61 armnn::armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_Tensor);
62 }
telsoa014fcda012018-03-09 14:13:49 +000063 };
64
telsoa01c577f2c2018-08-31 09:22:23 +010065 virtual void Manage() override
66 {
David Monahan3fb7e102019-08-20 11:25:29 +010067 // If we have enabled Importing, don't manage the tensor
68 if (!m_IsImportEnabled)
69 {
Colm Donelanb4ef1632024-02-01 15:00:43 +000070 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_MemoryGroup, "arm_compute::MemoryGroup is null.");
David Monahan3fb7e102019-08-20 11:25:29 +010071 m_MemoryGroup->manage(&m_Tensor);
72 }
telsoa01c577f2c2018-08-31 09:22:23 +010073 }
74
telsoa01c577f2c2018-08-31 09:22:23 +010075 virtual ITensorHandle* GetParent() const override { return nullptr; }
76
telsoa014fcda012018-03-09 14:13:49 +000077 virtual arm_compute::DataType GetDataType() const override
78 {
79 return m_Tensor.info()->data_type();
80 }
81
telsoa01c577f2c2018-08-31 09:22:23 +010082 virtual void SetMemoryGroup(const std::shared_ptr<arm_compute::IMemoryGroup>& memoryGroup) override
83 {
Jan Eilers3c9e0452020-04-10 13:00:44 +010084 m_MemoryGroup = PolymorphicPointerDowncast<arm_compute::MemoryGroup>(memoryGroup);
telsoa01c577f2c2018-08-31 09:22:23 +010085 }
86
87 virtual const void* Map(bool /* blocking = true */) const override
88 {
89 return static_cast<const void*>(m_Tensor.buffer() + m_Tensor.info()->offset_first_element_in_bytes());
90 }
telsoa01c577f2c2018-08-31 09:22:23 +010091
David Monahan3fb7e102019-08-20 11:25:29 +010092 virtual void Unmap() const override {}
telsoa01c577f2c2018-08-31 09:22:23 +010093
94 TensorShape GetStrides() const override
95 {
96 return armcomputetensorutils::GetStrides(m_Tensor.info()->strides_in_bytes());
97 }
98
99 TensorShape GetShape() const override
100 {
101 return armcomputetensorutils::GetShape(m_Tensor.info()->tensor_shape());
102 }
103
David Monahan3fb7e102019-08-20 11:25:29 +0100104 void SetImportFlags(MemorySourceFlags importFlags)
105 {
106 m_ImportFlags = importFlags;
107 }
108
109 MemorySourceFlags GetImportFlags() const override
110 {
111 return m_ImportFlags;
112 }
113
114 void SetImportEnabledFlag(bool importEnabledFlag)
115 {
116 m_IsImportEnabled = importEnabledFlag;
117 }
118
David Monahan0fa10502022-01-13 10:48:33 +0000119 bool CanBeImported(void* memory, MemorySource source) override
120 {
David Monahan3826ab62022-02-21 12:26:16 +0000121 if (source != MemorySource::Malloc || reinterpret_cast<uintptr_t>(memory) % m_TypeAlignment)
David Monahan0fa10502022-01-13 10:48:33 +0000122 {
123 return false;
124 }
125 return true;
126 }
127
David Monahan3fb7e102019-08-20 11:25:29 +0100128 virtual bool Import(void* memory, MemorySource source) override
129 {
Mike Kelly4cc341c2023-07-07 15:43:06 +0100130 if (m_ImportFlags& static_cast<MemorySourceFlags>(source))
David Monahan3fb7e102019-08-20 11:25:29 +0100131 {
132 if (source == MemorySource::Malloc && m_IsImportEnabled)
133 {
David Monahan0fa10502022-01-13 10:48:33 +0000134 if (!CanBeImported(memory, source))
David Monahan3fb7e102019-08-20 11:25:29 +0100135 {
136 throw MemoryImportException("NeonTensorHandle::Import Attempting to import unaligned memory");
137 }
138
139 // m_Tensor not yet Allocated
140 if (!m_Imported && !m_Tensor.buffer())
141 {
142 arm_compute::Status status = m_Tensor.allocator()->import_memory(memory);
143 // Use the overloaded bool operator of Status to check if it worked, if not throw an exception
144 // with the Status error message
145 m_Imported = bool(status);
146 if (!m_Imported)
147 {
148 throw MemoryImportException(status.error_description());
149 }
150 return m_Imported;
151 }
152
153 // m_Tensor.buffer() initially allocated with Allocate().
154 if (!m_Imported && m_Tensor.buffer())
155 {
156 throw MemoryImportException(
157 "NeonTensorHandle::Import Attempting to import on an already allocated tensor");
158 }
159
160 // m_Tensor.buffer() previously imported.
161 if (m_Imported)
162 {
163 arm_compute::Status status = m_Tensor.allocator()->import_memory(memory);
164 // Use the overloaded bool operator of Status to check if it worked, if not throw an exception
165 // with the Status error message
166 m_Imported = bool(status);
167 if (!m_Imported)
168 {
169 throw MemoryImportException(status.error_description());
170 }
171 return m_Imported;
172 }
173 }
Narumol Prangnawarata2493a02020-08-19 14:39:07 +0100174 else
175 {
176 throw MemoryImportException("NeonTensorHandle::Import is disabled");
177 }
178 }
179 else
180 {
181 throw MemoryImportException("NeonTensorHandle::Incorrect import flag");
David Monahan3fb7e102019-08-20 11:25:29 +0100182 }
183 return false;
184 }
185
Mike Kelly4cc341c2023-07-07 15:43:06 +0100186 virtual std::shared_ptr<ITensorHandle> DecorateTensorHandle(const TensorInfo& tensorInfo) override;
187
telsoa014fcda012018-03-09 14:13:49 +0000188private:
David Beck09e2f272018-10-30 11:38:41 +0000189 // Only used for testing
190 void CopyOutTo(void* memory) const override
191 {
192 switch (this->GetDataType())
193 {
194 case arm_compute::DataType::F32:
195 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
196 static_cast<float*>(memory));
197 break;
kevmay012b4d88e2019-01-24 14:05:09 +0000198 case arm_compute::DataType::U8:
David Beck09e2f272018-10-30 11:38:41 +0000199 case arm_compute::DataType::QASYMM8:
200 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
201 static_cast<uint8_t*>(memory));
202 break;
Sadik Armagan48f011e2021-04-21 10:50:34 +0100203 case arm_compute::DataType::QSYMM8:
Sadik Armagane5d0b932020-04-09 15:48:44 +0100204 case arm_compute::DataType::QASYMM8_SIGNED:
205 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
206 static_cast<int8_t*>(memory));
207 break;
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100208 case arm_compute::DataType::BFLOAT16:
209 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
210 static_cast<armnn::BFloat16*>(memory));
211 break;
Aron Virginas-Tar99836d32019-09-30 16:34:31 +0100212 case arm_compute::DataType::F16:
213 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
214 static_cast<armnn::Half*>(memory));
215 break;
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100216 case arm_compute::DataType::S16:
217 case arm_compute::DataType::QSYMM16:
218 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
219 static_cast<int16_t*>(memory));
220 break;
James Conroyd47a0642019-09-17 14:22:06 +0100221 case arm_compute::DataType::S32:
222 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
223 static_cast<int32_t*>(memory));
224 break;
David Beck09e2f272018-10-30 11:38:41 +0000225 default:
226 {
227 throw armnn::UnimplementedException();
228 }
229 }
230 }
231
232 // Only used for testing
233 void CopyInFrom(const void* memory) override
234 {
235 switch (this->GetDataType())
236 {
237 case arm_compute::DataType::F32:
238 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const float*>(memory),
239 this->GetTensor());
240 break;
kevmay012b4d88e2019-01-24 14:05:09 +0000241 case arm_compute::DataType::U8:
David Beck09e2f272018-10-30 11:38:41 +0000242 case arm_compute::DataType::QASYMM8:
243 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const uint8_t*>(memory),
244 this->GetTensor());
245 break;
Sadik Armagan48f011e2021-04-21 10:50:34 +0100246 case arm_compute::DataType::QSYMM8:
Sadik Armagane5d0b932020-04-09 15:48:44 +0100247 case arm_compute::DataType::QASYMM8_SIGNED:
Cathal Corbett06902652022-04-14 17:55:11 +0100248 case arm_compute::DataType::QSYMM8_PER_CHANNEL:
Sadik Armagane5d0b932020-04-09 15:48:44 +0100249 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int8_t*>(memory),
250 this->GetTensor());
251 break;
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100252 case arm_compute::DataType::BFLOAT16:
253 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const armnn::BFloat16*>(memory),
254 this->GetTensor());
255 break;
Aron Virginas-Tar99836d32019-09-30 16:34:31 +0100256 case arm_compute::DataType::F16:
257 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const armnn::Half*>(memory),
258 this->GetTensor());
259 break;
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100260 case arm_compute::DataType::S16:
261 case arm_compute::DataType::QSYMM16:
262 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int16_t*>(memory),
263 this->GetTensor());
264 break;
James Conroyd47a0642019-09-17 14:22:06 +0100265 case arm_compute::DataType::S32:
266 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int32_t*>(memory),
267 this->GetTensor());
268 break;
David Beck09e2f272018-10-30 11:38:41 +0000269 default:
270 {
271 throw armnn::UnimplementedException();
272 }
273 }
274 }
275
telsoa014fcda012018-03-09 14:13:49 +0000276 arm_compute::Tensor m_Tensor;
telsoa01c577f2c2018-08-31 09:22:23 +0100277 std::shared_ptr<arm_compute::MemoryGroup> m_MemoryGroup;
David Monahan3fb7e102019-08-20 11:25:29 +0100278 MemorySourceFlags m_ImportFlags;
279 bool m_Imported;
280 bool m_IsImportEnabled;
Finn Williamsb1aad422021-10-28 19:07:32 +0100281 const uintptr_t m_TypeAlignment;
Mike Kelly4cc341c2023-07-07 15:43:06 +0100282 std::vector<std::shared_ptr<NeonTensorHandleDecorator>> m_Decorated;
telsoa014fcda012018-03-09 14:13:49 +0000283};
284
Derek Lambertic81855f2019-06-13 17:34:19 +0100285class NeonSubTensorHandle : public IAclTensorHandle
telsoa014fcda012018-03-09 14:13:49 +0000286{
287public:
Derek Lambertic81855f2019-06-13 17:34:19 +0100288 NeonSubTensorHandle(IAclTensorHandle* parent,
telsoa01c577f2c2018-08-31 09:22:23 +0100289 const arm_compute::TensorShape& shape,
290 const arm_compute::Coordinates& coords)
Mike Kelly4cc341c2023-07-07 15:43:06 +0100291 : m_Tensor(&parent->GetTensor(), shape, coords, true)
telsoa014fcda012018-03-09 14:13:49 +0000292 {
telsoa01c577f2c2018-08-31 09:22:23 +0100293 parentHandle = parent;
telsoa014fcda012018-03-09 14:13:49 +0000294 }
295
296 arm_compute::ITensor& GetTensor() override { return m_Tensor; }
297 arm_compute::ITensor const& GetTensor() const override { return m_Tensor; }
telsoa01c577f2c2018-08-31 09:22:23 +0100298
299 virtual void Allocate() override {}
300 virtual void Manage() override {}
telsoa014fcda012018-03-09 14:13:49 +0000301
telsoa01c577f2c2018-08-31 09:22:23 +0100302 virtual ITensorHandle* GetParent() const override { return parentHandle; }
303
telsoa014fcda012018-03-09 14:13:49 +0000304 virtual arm_compute::DataType GetDataType() const override
305 {
306 return m_Tensor.info()->data_type();
307 }
308
telsoa01c577f2c2018-08-31 09:22:23 +0100309 virtual void SetMemoryGroup(const std::shared_ptr<arm_compute::IMemoryGroup>&) override {}
310
311 virtual const void* Map(bool /* blocking = true */) const override
312 {
313 return static_cast<const void*>(m_Tensor.buffer() + m_Tensor.info()->offset_first_element_in_bytes());
314 }
315 virtual void Unmap() const override {}
316
317 TensorShape GetStrides() const override
318 {
319 return armcomputetensorutils::GetStrides(m_Tensor.info()->strides_in_bytes());
320 }
321
322 TensorShape GetShape() const override
323 {
324 return armcomputetensorutils::GetShape(m_Tensor.info()->tensor_shape());
325 }
David Beck09e2f272018-10-30 11:38:41 +0000326
Mike Kelly4cc341c2023-07-07 15:43:06 +0100327 virtual std::shared_ptr<ITensorHandle> DecorateTensorHandle(const TensorInfo&) override
328 {
329 return nullptr;
330 };
331
telsoa014fcda012018-03-09 14:13:49 +0000332private:
David Beck09e2f272018-10-30 11:38:41 +0000333 // Only used for testing
334 void CopyOutTo(void* memory) const override
335 {
336 switch (this->GetDataType())
337 {
338 case arm_compute::DataType::F32:
339 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
340 static_cast<float*>(memory));
341 break;
kevmay012b4d88e2019-01-24 14:05:09 +0000342 case arm_compute::DataType::U8:
David Beck09e2f272018-10-30 11:38:41 +0000343 case arm_compute::DataType::QASYMM8:
344 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
345 static_cast<uint8_t*>(memory));
346 break;
Sadik Armagan48f011e2021-04-21 10:50:34 +0100347 case arm_compute::DataType::QSYMM8:
Sadik Armagane5d0b932020-04-09 15:48:44 +0100348 case arm_compute::DataType::QASYMM8_SIGNED:
349 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
350 static_cast<int8_t*>(memory));
351 break;
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100352 case arm_compute::DataType::S16:
353 case arm_compute::DataType::QSYMM16:
354 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
355 static_cast<int16_t*>(memory));
356 break;
James Conroyd47a0642019-09-17 14:22:06 +0100357 case arm_compute::DataType::S32:
358 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
359 static_cast<int32_t*>(memory));
360 break;
David Beck09e2f272018-10-30 11:38:41 +0000361 default:
362 {
363 throw armnn::UnimplementedException();
364 }
365 }
366 }
367
368 // Only used for testing
369 void CopyInFrom(const void* memory) override
370 {
371 switch (this->GetDataType())
372 {
373 case arm_compute::DataType::F32:
374 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const float*>(memory),
375 this->GetTensor());
376 break;
kevmay012b4d88e2019-01-24 14:05:09 +0000377 case arm_compute::DataType::U8:
David Beck09e2f272018-10-30 11:38:41 +0000378 case arm_compute::DataType::QASYMM8:
379 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const uint8_t*>(memory),
380 this->GetTensor());
381 break;
Sadik Armagan48f011e2021-04-21 10:50:34 +0100382 case arm_compute::DataType::QSYMM8:
Sadik Armagane5d0b932020-04-09 15:48:44 +0100383 case arm_compute::DataType::QASYMM8_SIGNED:
384 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int8_t*>(memory),
385 this->GetTensor());
386 break;
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100387 case arm_compute::DataType::S16:
388 case arm_compute::DataType::QSYMM16:
389 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int16_t*>(memory),
390 this->GetTensor());
391 break;
James Conroyd47a0642019-09-17 14:22:06 +0100392 case arm_compute::DataType::S32:
393 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int32_t*>(memory),
394 this->GetTensor());
395 break;
David Beck09e2f272018-10-30 11:38:41 +0000396 default:
397 {
398 throw armnn::UnimplementedException();
399 }
400 }
401 }
402
telsoa01c577f2c2018-08-31 09:22:23 +0100403 arm_compute::SubTensor m_Tensor;
404 ITensorHandle* parentHandle = nullptr;
telsoa014fcda012018-03-09 14:13:49 +0000405};
406
Mike Kelly4cc341c2023-07-07 15:43:06 +0100407/// NeonTensorDecorator wraps an existing Neon tensor allowing us to override the TensorInfo for it
408class NeonTensorDecorator : public arm_compute::ITensor
409{
410public:
411 NeonTensorDecorator();
412
413 NeonTensorDecorator(arm_compute::ITensor* original, const TensorInfo& info);
414
415 ~NeonTensorDecorator() = default;
416
417 NeonTensorDecorator(const NeonTensorDecorator&) = delete;
418
419 NeonTensorDecorator& operator=(const NeonTensorDecorator&) = delete;
420
421 NeonTensorDecorator(NeonTensorDecorator&&) = default;
422
423 NeonTensorDecorator& operator=(NeonTensorDecorator&&) = default;
424
425 // Inherited methods overridden:
426 arm_compute::ITensorInfo* info() const override;
427
428 arm_compute::ITensorInfo* info() override;
429
430 uint8_t* buffer() const override;
431
432private:
433 arm_compute::ITensor* m_Original;
434 mutable arm_compute::TensorInfo m_TensorInfo;
435};
436
437class NeonTensorHandleDecorator : public IAclTensorHandle
438{
439public:
440 NeonTensorHandleDecorator(IAclTensorHandle* parent, const TensorInfo& info)
441 : m_Tensor(&parent->GetTensor(), info)
442 {
443 parentHandle = parent;
444 }
445
446 arm_compute::ITensor& GetTensor() override { return m_Tensor; }
447 arm_compute::ITensor const& GetTensor() const override { return m_Tensor; }
448
449 virtual void Allocate() override {}
450 virtual void Manage() override {}
451
452 virtual ITensorHandle* GetParent() const override { return nullptr; }
453
454 virtual arm_compute::DataType GetDataType() const override
455 {
456 return m_Tensor.info()->data_type();
457 }
458
459 virtual void SetMemoryGroup(const std::shared_ptr<arm_compute::IMemoryGroup>&) override {}
460
461 virtual const void* Map(bool /* blocking = true */) const override
462 {
463 return static_cast<const void*>(m_Tensor.buffer() + m_Tensor.info()->offset_first_element_in_bytes());
464 }
465 virtual void Unmap() const override {}
466
467 TensorShape GetStrides() const override
468 {
469 return armcomputetensorutils::GetStrides(m_Tensor.info()->strides_in_bytes());
470 }
471
472 TensorShape GetShape() const override
473 {
474 return armcomputetensorutils::GetShape(m_Tensor.info()->tensor_shape());
475 }
476
477 virtual std::shared_ptr<ITensorHandle> DecorateTensorHandle(const TensorInfo&) override
478 {
479 return nullptr;
480 };
481
482private:
483 // Only used for testing
484 void CopyOutTo(void* memory) const override
485 {
486 switch (this->GetDataType())
487 {
488 case arm_compute::DataType::F32:
489 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
490 static_cast<float*>(memory));
491 break;
492 case arm_compute::DataType::U8:
493 case arm_compute::DataType::QASYMM8:
494 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
495 static_cast<uint8_t*>(memory));
496 break;
497 case arm_compute::DataType::QSYMM8:
498 case arm_compute::DataType::QASYMM8_SIGNED:
499 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
500 static_cast<int8_t*>(memory));
501 break;
502 case arm_compute::DataType::S16:
503 case arm_compute::DataType::QSYMM16:
504 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
505 static_cast<int16_t*>(memory));
506 break;
507 case arm_compute::DataType::S32:
508 armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
509 static_cast<int32_t*>(memory));
510 break;
511 default:
512 {
513 throw armnn::UnimplementedException();
514 }
515 }
516 }
517
518 // Only used for testing
519 void CopyInFrom(const void* memory) override
520 {
521 switch (this->GetDataType())
522 {
523 case arm_compute::DataType::F32:
524 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const float*>(memory),
525 this->GetTensor());
526 break;
527 case arm_compute::DataType::U8:
528 case arm_compute::DataType::QASYMM8:
529 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const uint8_t*>(memory),
530 this->GetTensor());
531 break;
532 case arm_compute::DataType::QSYMM8:
533 case arm_compute::DataType::QASYMM8_SIGNED:
534 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int8_t*>(memory),
535 this->GetTensor());
536 break;
537 case arm_compute::DataType::S16:
538 case arm_compute::DataType::QSYMM16:
539 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int16_t*>(memory),
540 this->GetTensor());
541 break;
542 case arm_compute::DataType::S32:
543 armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int32_t*>(memory),
544 this->GetTensor());
545 break;
546 default:
547 {
548 throw armnn::UnimplementedException();
549 }
550 }
551 }
552
553 NeonTensorDecorator m_Tensor;
554 ITensorHandle* parentHandle = nullptr;
555};
556
557
Aron Virginas-Tar99836d32019-09-30 16:34:31 +0100558} // namespace armnn