xref: /aosp_15_r20/external/armnn/src/backends/tosaReference/TosaRefTensorHandle.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "TosaRefTensorHandle.hpp"
6 
7 namespace armnn
8 {
9 
TosaRefTensorHandle(const TensorInfo & tensorInfo,std::shared_ptr<TosaRefMemoryManager> & memoryManager)10 TosaRefTensorHandle::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 
TosaRefTensorHandle(const TensorInfo & tensorInfo,MemorySourceFlags importFlags)21 TosaRefTensorHandle::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 
~TosaRefTensorHandle()31 TosaRefTensorHandle::~TosaRefTensorHandle()
32 {
33     if (!m_Pool)
34     {
35         // unmanaged
36         if (!m_Imported)
37         {
38             ::operator delete(m_UnmanagedMemory);
39         }
40     }
41 }
42 
Manage()43 void 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 
Allocate()54 void 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 
Map(bool) const80 const void* TosaRefTensorHandle::Map(bool /*unused*/) const
81 {
82     return GetPointer();
83 }
84 
GetPointer() const85 void* 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 
CopyOutTo(void * dest) const101 void TosaRefTensorHandle::CopyOutTo(void* dest) const
102 {
103     const void *src = GetPointer();
104     ARMNN_ASSERT(src);
105     memcpy(dest, src, m_TensorInfo.GetNumBytes());
106 }
107 
CopyInFrom(const void * src)108 void TosaRefTensorHandle::CopyInFrom(const void* src)
109 {
110     void *dest = GetPointer();
111     ARMNN_ASSERT(dest);
112     memcpy(dest, src, m_TensorInfo.GetNumBytes());
113 }
114 
Import(void * memory,MemorySource source)115 bool 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 
CanBeImported(void * memory,MemorySource source)158 bool 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 }
176