9 #include <arm_compute/core/Types.h> 10 #include <arm_compute/runtime/CL/CLBufferAllocator.h> 13 #include <arm_compute/runtime/CL/CLMemoryRegion.h> 15 #include <arm_compute/core/CL/CLKernelLibrary.h> 16 #include <CL/cl_ext.h> 27 {
"NonConstWeights",
false},
28 {
"AsyncExecution",
false},
29 {
"ProtectedContentAllocation",
true}
36 ClBackend(std::shared_ptr<ICustomAllocator> allocator)
99 m_CustomAllocator = std::make_shared<ClBackendCustomAllocatorWrapper>(std::move(allocator));
111 void*
allocate(
size_t size,
size_t alignment)
override 113 auto alloc = m_CustomAllocator->allocate(size, alignment);
114 return MapAllocatedMemory(alloc, size, m_CustomAllocator->GetMemorySourceType());
118 auto hostMemPtr = m_AllocatedBufferMappings[ptr];
119 clReleaseMemObject(static_cast<cl_mem>(ptr));
120 m_CustomAllocator->free(hostMemPtr);
122 std::unique_ptr<arm_compute::IMemoryRegion>
make_region(
size_t size,
size_t alignment)
override 124 auto hostMemPtr = m_CustomAllocator->allocate(size, alignment);
125 cl_mem buffer = MapAllocatedMemory(hostMemPtr, size, m_CustomAllocator->GetMemorySourceType());
127 return std::make_unique<ClBackendCustomAllocatorMemoryRegion>(cl::Buffer(buffer),
129 m_CustomAllocator->GetMemorySourceType());
132 cl_mem MapAllocatedMemory(
void* memory,
size_t size,
MemorySource source)
135 auto cachelineAlignment =
136 arm_compute::CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE>();
137 auto roundedSize = cachelineAlignment + size - (size % cachelineAlignment);
141 const cl_import_properties_arm importProperties[] =
144 CL_IMPORT_TYPE_HOST_ARM,
147 cl_int
error = CL_SUCCESS;
148 cl_mem buffer = clImportMemoryARM(arm_compute::CLKernelLibrary::get().context().
get(),
154 if (error == CL_SUCCESS)
156 m_AllocatedBufferMappings.insert(std::make_pair(static_cast<void *>(buffer), memory));
160 "Mapping allocated memory from CustomMemoryAllocator failed, errcode: " + std::to_string(error));
164 const cl_import_properties_arm importProperties[] =
167 CL_IMPORT_TYPE_DMA_BUF_ARM,
168 CL_IMPORT_DMA_BUF_DATA_CONSISTENCY_WITH_HOST_ARM,
172 cl_int
error = CL_SUCCESS;
173 cl_mem buffer = clImportMemoryARM(arm_compute::CLKernelLibrary::get().context().
get(),
179 if (error == CL_SUCCESS)
181 m_AllocatedBufferMappings.insert(std::make_pair(static_cast<void *>(buffer), memory));
185 "Mapping allocated memory from CustomMemoryAllocator failed, errcode: " 186 + std::to_string(error));
190 const cl_import_properties_arm importProperties[] =
193 CL_IMPORT_TYPE_DMA_BUF_ARM,
194 CL_IMPORT_TYPE_PROTECTED_ARM,
198 cl_int
error = CL_SUCCESS;
199 cl_mem buffer = clImportMemoryARM(arm_compute::CLKernelLibrary::get().context().
get(),
205 if (error == CL_SUCCESS)
207 m_AllocatedBufferMappings.insert(std::make_pair(static_cast<void *>(buffer), memory));
211 "Mapping allocated memory from CustomMemoryAllocator failed, errcode: " 212 + std::to_string(error));
215 "Attempting to allocate memory with unsupported MemorySource type in CustomAllocator");
217 std::shared_ptr<ICustomAllocator> m_CustomAllocator;
218 std::map<void*, void*> m_AllocatedBufferMappings;
226 : ICLMemoryRegion(buffer.getInfo<CL_MEM_SIZE>())
229 m_HostMemPtr = hostMemPtr;
230 m_MemorySource = source;
239 void*
map(cl::CommandQueue &q,
bool blocking)
override 242 if (m_HostMemPtr ==
nullptr)
244 throw armnn::Exception(
"ClBackend: Attempting to map memory with an invalid host ptr");
246 if (_mapping !=
nullptr)
248 throw armnn::Exception(
"ClBackend: Attempting to map memory which has not yet been unmapped");
250 switch (m_MemorySource)
253 _mapping = m_HostMemPtr;
259 _mapping = mmap(NULL, _size, PROT_WRITE, MAP_SHARED, *(reinterpret_cast<int*>(m_HostMemPtr)), 0);
263 throw armnn::Exception(
"ClBackend: Attempting to map imported memory without a valid source");
268 void unmap(cl::CommandQueue &q)
override 271 switch (m_MemorySource)
278 munmap(_mapping, _size);
282 throw armnn::Exception(
"ClBackend: Attempting to unmap imported memory without a valid source");
287 void* m_HostMemPtr =
nullptr;
void * map(cl::CommandQueue &q, bool blocking) override
ClBackend(std::shared_ptr< ICustomAllocator > allocator)
void free(void *ptr) override
std::unique_ptr< IWorkloadFactory > IWorkloadFactoryPtr
std::vector< OptimizationPtr > Optimizations
std::vector< BackendOptions > ModelOptions
std::unique_ptr< arm_compute::IMemoryRegion > make_region(size_t size, size_t alignment) override
#define ARMNN_LOG(severity)
void unmap(cl::CommandQueue &q) override
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
unsigned int MemorySourceFlags
Copyright (c) 2021 ARM Limited and Contributors.
std::unique_ptr< IMemoryManager > IMemoryManagerUniquePtr
void IgnoreUnused(Ts &&...)
IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override
void RegisterTensorHandleFactories(TensorHandleFactoryRegistry ®istry) override
(Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFa...
The SubgraphView class represents a subgraph of a Graph.
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
std::unique_ptr< armnn::profiling::IBackendProfiling > IBackendProfilingPtr
BackendCapabilities GetCapabilities() const override
Returns a BackendCapability if the backend lists the capability The BackendCapability must then be in...
OptimizationViews OptimizeSubgraphView(const SubgraphView &subgraph, const ModelOptions &modelOptions) const override
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions &) const override
Create the runtime context of the backend.
std::vector< ITensorHandleFactory::FactoryId > GetHandleFactoryPreferences() const override
(Optional) Returns a vector of supported TensorHandleFactory ids in preference order.
virtual bool UseCustomMemoryAllocator(std::shared_ptr< ICustomAllocator > allocator, armnn::Optional< std::string &> errMsg) override
Signals the backend to use a custom memory allocator provided by the user.
BackendOptions BackendCapabilities
IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr &memoryManager=nullptr) const override
const BackendCapabilities gpuAccCapabilities("GpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false}, {"ProtectedContentAllocation", true} })
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr
Struct for the users to pass backend specific options.
const BackendId & GetId() const override
IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override
Base class for all ArmNN exceptions so that users can filter to just those.
MemorySource
Define the Memory Source to reduce copies.
IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(const IRuntime::CreationOptions &, IBackendProfilingPtr &backendProfiling) override
Create context specifically used for profiling interaction from backends.
bool m_UsingCustomAllocator
ClBackendCustomAllocatorMemoryRegion(const cl::Buffer &buffer, void *hostMemPtr, armnn::MemorySource source)
void * allocate(size_t size, size_t alignment) override
IBackendInternal::Optimizations GetOptimizations() const override
static const BackendId & GetIdStatic()
ClBackendCustomAllocatorWrapper(std::shared_ptr< ICustomAllocator > alloc)
std::shared_ptr< armnn::profiling::IBackendProfilingContext > IBackendProfilingContextPtr
This is the bridge between backend and backend profiling we'll keep it in the backend namespace...
std::unique_ptr< IBackendContext > IBackendContextPtr