blob: 38d02f1bb6b627c9530ff79b22c9ba6e46ef93d5 [file] [log] [blame]
Francis Murtaghbf354142022-08-12 13:54:17 +01001//
2// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5#include "TosaRefTensorHandle.hpp"
6
7namespace armnn
8{
9
10TosaRefTensorHandle::TosaRefTensorHandle(const TensorInfo& tensorInfo,
11 std::shared_ptr<TosaRefMemoryManager>& memoryManager)
12 : m_TensorInfo(tensorInfo)
13 , m_MemoryManager(memoryManager)
14 , m_Pool(nullptr)
15 , m_UnmanagedMemory(nullptr)
16 , m_ImportFlags(static_cast<MemorySourceFlags>(MemorySource::Undefined))
17 , m_Imported(false)
18 , m_IsImportEnabled(false)
19{}
20
21TosaRefTensorHandle::TosaRefTensorHandle(const TensorInfo& tensorInfo,
22 MemorySourceFlags importFlags)
23 : m_TensorInfo(tensorInfo)
24 , m_Pool(nullptr)
25 , m_UnmanagedMemory(nullptr)
26 , m_ImportFlags(importFlags)
27 , m_Imported(false)
28 , m_IsImportEnabled(true)
29{}
30
31TosaRefTensorHandle::~TosaRefTensorHandle()
32{
33 if (!m_Pool)
34 {
35 // unmanaged
36 if (!m_Imported)
37 {
38 ::operator delete(m_UnmanagedMemory);
39 }
40 }
41}
42
43void TosaRefTensorHandle::Manage()
44{
45 if (!m_IsImportEnabled)
46 {
47 ARMNN_ASSERT_MSG(!m_Pool, "TosaRefTensorHandle::Manage() called twice");
48 ARMNN_ASSERT_MSG(!m_UnmanagedMemory, "TosaRefTensorHandle::Manage() called after Allocate()");
49
50 m_Pool = m_MemoryManager->Manage(m_TensorInfo.GetNumBytes());
51 }
52}
53
54void TosaRefTensorHandle::Allocate()
55{
56 // If import is enabled, do not allocate the tensor
57 if (!m_IsImportEnabled)
58 {
59
60 if (!m_UnmanagedMemory)
61 {
62 if (!m_Pool)
63 {
64 // unmanaged
65 m_UnmanagedMemory = ::operator new(m_TensorInfo.GetNumBytes());
66 }
67 else
68 {
69 m_MemoryManager->Allocate(m_Pool);
70 }
71 }
72 else
73 {
74 throw InvalidArgumentException("TosaRefTensorHandle::Allocate Trying to allocate a TosaRefTensorHandle"
75 "that already has allocated memory.");
76 }
77 }
78}
79
80const void* TosaRefTensorHandle::Map(bool /*unused*/) const
81{
82 return GetPointer();
83}
84
85void* TosaRefTensorHandle::GetPointer() const
86{
87 if (m_UnmanagedMemory)
88 {
89 return m_UnmanagedMemory;
90 }
91 else if (m_Pool)
92 {
93 return m_MemoryManager->GetPointer(m_Pool);
94 }
95 else
96 {
97 throw NullPointerException("TosaRefTensorHandle::GetPointer called on unmanaged, unallocated tensor handle");
98 }
99}
100
101void TosaRefTensorHandle::CopyOutTo(void* dest) const
102{
103 const void *src = GetPointer();
104 ARMNN_ASSERT(src);
105 memcpy(dest, src, m_TensorInfo.GetNumBytes());
106}
107
108void TosaRefTensorHandle::CopyInFrom(const void* src)
109{
110 void *dest = GetPointer();
111 ARMNN_ASSERT(dest);
112 memcpy(dest, src, m_TensorInfo.GetNumBytes());
113}
114
115bool TosaRefTensorHandle::Import(void* memory, MemorySource source)
116{
117 if (m_ImportFlags & static_cast<MemorySourceFlags>(source))
118 {
119 if (m_IsImportEnabled && source == MemorySource::Malloc)
120 {
121 // Check memory alignment
122 if(!CanBeImported(memory, source))
123 {
124 if (m_Imported)
125 {
126 m_Imported = false;
127 m_UnmanagedMemory = nullptr;
128 }
129 return false;
130 }
131
132 // m_UnmanagedMemory not yet allocated.
133 if (!m_Imported && !m_UnmanagedMemory)
134 {
135 m_UnmanagedMemory = memory;
136 m_Imported = true;
137 return true;
138 }
139
140 // m_UnmanagedMemory initially allocated with Allocate().
141 if (!m_Imported && m_UnmanagedMemory)
142 {
143 return false;
144 }
145
146 // m_UnmanagedMemory previously imported.
147 if (m_Imported)
148 {
149 m_UnmanagedMemory = memory;
150 return true;
151 }
152 }
153 }
154
155 return false;
156}
157
158bool TosaRefTensorHandle::CanBeImported(void* memory, MemorySource source)
159{
160 if (m_ImportFlags & static_cast<MemorySourceFlags>(source))
161 {
162 if (m_IsImportEnabled && source == MemorySource::Malloc)
163 {
164 uintptr_t alignment = GetDataTypeSize(m_TensorInfo.GetDataType());
165 if (reinterpret_cast<uintptr_t>(memory) % alignment)
166 {
167 return false;
168 }
169 return true;
170 }
171 }
172 return false;
173}
174
175}