blob: bc221adbe36fdc2677c08df5522fb5a4572e4509 [file] [log] [blame]
James Conroy1f58f032021-04-27 17:13:27 +01001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5#include <armnn/Exceptions.hpp>
6#include <armnn/utility/IgnoreUnused.hpp>
7
Colm Donelan0c479742021-12-10 12:43:54 +00008#include <armnn/backends/TensorHandle.hpp>
James Conroy1f58f032021-04-27 17:13:27 +01009
10#include <cstring>
11
12namespace armnn
13{
14
15TensorShape GetUnpaddedTensorStrides(const TensorInfo& tensorInfo)
16{
17 TensorShape shape(tensorInfo.GetShape());
18 auto size = GetDataTypeSize(tensorInfo.GetDataType());
19 auto runningSize = size;
20 std::vector<unsigned int> strides(shape.GetNumDimensions());
21 auto lastIdx = shape.GetNumDimensions()-1;
22 for (unsigned int i=0; i < lastIdx ; i++)
23 {
24 strides[lastIdx-i] = runningSize;
25 runningSize *= shape[lastIdx-i];
26 }
27 strides[0] = runningSize;
28 return TensorShape(shape.GetNumDimensions(), strides.data());
29}
30
31ConstTensorHandle::ConstTensorHandle(const TensorInfo& tensorInfo)
32: m_TensorInfo(tensorInfo)
33, m_Memory(nullptr)
34{
35}
36
37template <>
38const void* ConstTensorHandle::GetConstTensor<void>() const
39{
40 return m_Memory;
41}
42
43TensorHandle::TensorHandle(const TensorInfo& tensorInfo)
44: ConstTensorHandle(tensorInfo)
45, m_MutableMemory(nullptr)
46{
47}
48
49template <>
50void* TensorHandle::GetTensor<void>() const
51{
52 return m_MutableMemory;
53}
54
55ScopedTensorHandle::ScopedTensorHandle(const TensorInfo& tensorInfo)
56: TensorHandle(tensorInfo)
57{
58}
59
60ScopedTensorHandle::ScopedTensorHandle(const ConstTensor& tensor)
61: ScopedTensorHandle(tensor.GetInfo())
62{
63 CopyFrom(tensor.GetMemoryArea(), tensor.GetNumBytes());
64}
65
66ScopedTensorHandle::ScopedTensorHandle(const ConstTensorHandle& tensorHandle)
67: ScopedTensorHandle(tensorHandle.GetTensorInfo())
68{
69 CopyFrom(tensorHandle.GetConstTensor<void>(), tensorHandle.GetTensorInfo().GetNumBytes());
70}
71
72ScopedTensorHandle::ScopedTensorHandle(const ScopedTensorHandle& other)
73: TensorHandle(other.GetTensorInfo())
74{
75 CopyFrom(other);
76}
77
78ScopedTensorHandle& ScopedTensorHandle::operator=(const ScopedTensorHandle& other)
79{
80 ::operator delete(GetTensor<void>());
81 SetMemory(nullptr);
82 CopyFrom(other);
83 return *this;
84}
85
86ScopedTensorHandle::~ScopedTensorHandle()
87{
88 ::operator delete(GetTensor<void>());
89}
90
91void ScopedTensorHandle::Allocate()
92{
93 if (GetTensor<void>() == nullptr)
94 {
95 SetMemory(::operator new(GetTensorInfo().GetNumBytes()));
96 }
97 else
98 {
99 throw InvalidArgumentException("TensorHandle::Allocate Trying to allocate a TensorHandle"
100 "that already has allocated memory.");
101 }
102}
103
104void ScopedTensorHandle::CopyOutTo(void* memory) const
105{
David Monahan6a1d5062023-08-29 09:10:50 +0100106 const void* src = GetTensor<void>();
107 if (src == nullptr)
108 {
109 throw NullPointerException("TensorHandle::CopyOutTo called with a null src pointer");
110 }
111 if (memory == nullptr)
112 {
113 throw NullPointerException("TensorHandle::CopyOutTo called with a null dest pointer");
114 }
115 memcpy(memory, src, GetTensorInfo().GetNumBytes());
James Conroy1f58f032021-04-27 17:13:27 +0100116}
117
118void ScopedTensorHandle::CopyInFrom(const void* memory)
119{
David Monahan6a1d5062023-08-29 09:10:50 +0100120 void* dest = GetTensor<void>();
121 if (dest == nullptr)
122 {
123 throw NullPointerException("TensorHandle::CopyInFrom called with a null dest pointer");
124 }
125 if (memory == nullptr)
126 {
127 throw NullPointerException("TensorHandle::CopyInFrom called with a null src pointer");
128 }
129 memcpy(dest, memory, GetTensorInfo().GetNumBytes());
James Conroy1f58f032021-04-27 17:13:27 +0100130}
131
132void ScopedTensorHandle::CopyFrom(const ScopedTensorHandle& other)
133{
134 CopyFrom(other.GetTensor<void>(), other.GetTensorInfo().GetNumBytes());
135}
136
137void ScopedTensorHandle::CopyFrom(const void* srcMemory, unsigned int numBytes)
138{
David Monahan6a1d5062023-08-29 09:10:50 +0100139 if (GetTensor<void>() != nullptr)
140 {
141 throw NullPointerException("TensorHandle::CopyFrom called on an already allocated TensorHandle");
142 }
143 if (GetTensorInfo().GetNumBytes() != numBytes)
144 {
145 std::stringstream msg;
146 msg << "TensorHandle:CopyFrom: Number of bytes in the tensor info (" << GetTensorInfo().GetNumBytes() <<
147 ") does not match the number of bytes being copied (" << numBytes << ")";
148 throw armnn::Exception(msg.str());
149 }
James Conroy1f58f032021-04-27 17:13:27 +0100150
151 if (srcMemory)
152 {
153 Allocate();
154 memcpy(GetTensor<void>(), srcMemory, numBytes);
155 }
156}
157
158void PassthroughTensorHandle::Allocate()
159{
160 throw InvalidArgumentException("PassthroughTensorHandle::Allocate() should never be called");
161}
162
163void ConstPassthroughTensorHandle::Allocate()
164{
165 throw InvalidArgumentException("ConstPassthroughTensorHandle::Allocate() should never be called");
166}
167
168} // namespace armnn