1 /* 2 * Copyright (c) Qualcomm Innovation Center, Inc. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 #pragma once 9 #include <QnnTypes.h> 10 #include <executorch/backends/qualcomm/runtime/QnnExecuTorch.h> 11 #include <executorch/runtime/core/error.h> 12 #include <atomic> 13 #include <cstdint> 14 #include <memory> 15 #include <mutex> 16 #include <unordered_map> 17 #include <unordered_set> 18 19 using RpcMemAllocFn_t = void* (*)(int, uint32_t, int); 20 using RpcMemFreeFn_t = void (*)(void*); 21 using RpcMemToFdFn_t = int (*)(void*); 22 23 // TODO Finad a better file to place CustomMemTensorInfo 24 bool operator==(const CustomMemTensorInfo& lhs, const CustomMemTensorInfo& rhs); 25 template <> 26 struct std::hash<CustomMemTensorInfo> { 27 std::size_t operator()(const CustomMemTensorInfo& info) const noexcept; 28 }; 29 30 namespace executorch { 31 namespace backends { 32 namespace qnn { 33 34 class SharedBuffer final { 35 public: 36 SharedBuffer(const SharedBuffer&) = delete; 37 SharedBuffer& operator=(const SharedBuffer&) = delete; 38 SharedBuffer(SharedBuffer&&) = delete; 39 SharedBuffer& operator=(SharedBuffer&&) = delete; 40 ~SharedBuffer(); 41 42 static SharedBuffer& GetSharedBufferManager(); 43 void* AllocMem(size_t bytes, size_t alignment); 44 // map a buffer allocated via RPCMem to a file descriptor so it can be 45 // registered with a backend via QnnMem_register() 46 int32_t MemToFd(void* buf); 47 48 void FreeMem(void* buf); 49 50 bool IsAllocated(void* buf); 51 52 bool GetInitialize() { 53 return initialize_; 54 } 55 void SetInitialize(bool initialize) { 56 initialize_ = initialize; 57 } 58 59 // memory handle is registered during execution 60 void AddCusomMemTensorAddr(void* tensor_addr, void* custom_mem); 61 62 // memory handle can be registered before execution 63 void AddCusomMemTensorInfo(const CustomMemTensorInfo& info); 64 65 size_t GetAllocatedSize(void* buf); 66 67 void* GetCustomMemBase(void* buf); 68 69 void* GetUnAlignedAddr(void* buf); 70 71 const std::unordered_set<CustomMemTensorInfo>& GetCustomMemTensorInfoSet() { 72 return custom_mem_tensor_info_set_; 73 }; 74 75 private: 76 SharedBuffer() = default; 77 78 // dlopen RPCMem library and dlysm required functions 79 executorch::runtime::Error Load(); 80 81 executorch::runtime::Error UnLoad(); 82 83 // Pointer to the dlopen'd libcdsprpc.so shared library which contains 84 // rpcmem_alloc, rpcmem_free, rpcmem_to_fd APIs 85 void* lib_cdsp_rpc_; 86 // Function pointer to rpcmem_alloc 87 RpcMemAllocFn_t rpc_mem_alloc_; 88 // Function pointer to rpcmem_free 89 RpcMemFreeFn_t rpc_mem_free_; 90 // Function pointer to rpcmem_to_fd 91 RpcMemToFdFn_t rpc_mem_to_fd_; 92 std::unordered_map<void*, void*> restore_map_; 93 std::unordered_map<void*, size_t> allocated_size_map_; 94 // Maps for the custom memory 95 std::unordered_map<void*, void*> tensor_addr_to_custom_mem_; 96 std::unordered_set<CustomMemTensorInfo> custom_mem_tensor_info_set_; 97 std::atomic_bool initialize_{false}; 98 static std::mutex init_mutex_; 99 }; 100 101 } // namespace qnn 102 } // namespace backends 103 } // namespace executorch 104