1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one |
3 | * or more contributor license agreements. See the NOTICE file |
4 | * distributed with this work for additional information |
5 | * regarding copyright ownership. The ASF licenses this file |
6 | * to you under the Apache License, Version 2.0 (the |
7 | * "License"); you may not use this file except in compliance |
8 | * with the License. You may obtain a copy of the License at |
9 | * |
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * |
12 | * Unless required by applicable law or agreed to in writing, |
13 | * software distributed under the License is distributed on an |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
15 | * KIND, either express or implied. See the License for the |
16 | * specific language governing permissions and limitations |
17 | * under the License. |
18 | */ |
19 | |
20 | /*! |
21 | * \file dso_libary.cc |
22 | * \brief Create library module to load from dynamic shared library. |
23 | */ |
24 | #include <tvm/runtime/memory.h> |
25 | #include <tvm/runtime/module.h> |
26 | #include <tvm/runtime/packed_func.h> |
27 | #include <tvm/runtime/registry.h> |
28 | |
29 | #include "library_module.h" |
30 | |
31 | #if defined(_WIN32) |
32 | #include <windows.h> |
33 | #else |
34 | #include <dlfcn.h> |
35 | #endif |
36 | |
37 | #if defined(__hexagon__) |
38 | extern "C" { |
39 | #include <HAP_farf.h> |
40 | } |
41 | #endif |
42 | |
43 | namespace tvm { |
44 | namespace runtime { |
45 | |
46 | /*! |
47 | * \brief Dynamic shared library object used to load |
48 | * and retrieve symbols by name. This is the default |
49 | * module TVM uses for host-side AOT compilation. |
50 | */ |
51 | class DSOLibrary final : public Library { |
52 | public: |
53 | ~DSOLibrary(); |
54 | /*! |
55 | * \brief Initialize by loading and storing |
56 | * a handle to the underlying shared library. |
57 | * \param name The string name/path to the |
58 | * shared library over which to initialize. |
59 | */ |
60 | void Init(const std::string& name); |
61 | /*! |
62 | * \brief Returns the symbol address within |
63 | * the shared library for a given symbol name. |
64 | * \param name The name of the symbol. |
65 | * \return The symbol. |
66 | */ |
67 | void* GetSymbol(const char* name) final; |
68 | |
69 | private: |
70 | /*! \brief Private implementation of symbol lookup. |
71 | * Implementation is operating system dependent. |
72 | * \param The name of the symbol. |
73 | * \return The symbol. |
74 | */ |
75 | void* GetSymbol_(const char* name); |
76 | /*! \brief Implementation of shared library load. |
77 | * Implementation is operating system dependent. |
78 | * \param The name/path of the shared library. |
79 | */ |
80 | void Load(const std::string& name); |
81 | /*! \brief Implementation of shared library unload. |
82 | * Implementation is operating system dependent. |
83 | */ |
84 | void Unload(); |
85 | |
86 | #if defined(_WIN32) |
87 | //! \brief Windows library handle |
88 | HMODULE lib_handle_{nullptr}; |
89 | #else |
90 | // \brief Linux library handle |
91 | void* lib_handle_{nullptr}; |
92 | #endif |
93 | }; |
94 | |
95 | DSOLibrary::~DSOLibrary() { |
96 | if (lib_handle_) Unload(); |
97 | } |
98 | |
99 | void DSOLibrary::Init(const std::string& name) { Load(name); } |
100 | |
101 | void* DSOLibrary::GetSymbol(const char* name) { return GetSymbol_(name); } |
102 | |
103 | #if defined(_WIN32) |
104 | |
105 | void* DSOLibrary::GetSymbol_(const char* name) { |
106 | return reinterpret_cast<void*>(GetProcAddress(lib_handle_, (LPCSTR)name)); // NOLINT(*) |
107 | } |
108 | |
109 | void DSOLibrary::Load(const std::string& name) { |
110 | // use wstring version that is needed by LLVM. |
111 | std::wstring wname(name.begin(), name.end()); |
112 | lib_handle_ = LoadLibraryW(wname.c_str()); |
113 | ICHECK(lib_handle_ != nullptr) << "Failed to load dynamic shared library " << name; |
114 | } |
115 | |
116 | void DSOLibrary::Unload() { |
117 | FreeLibrary(lib_handle_); |
118 | lib_handle_ = nullptr; |
119 | } |
120 | |
121 | #else |
122 | |
123 | void DSOLibrary::Load(const std::string& name) { |
124 | lib_handle_ = dlopen(name.c_str(), RTLD_LAZY | RTLD_LOCAL); |
125 | ICHECK(lib_handle_ != nullptr) << "Failed to load dynamic shared library " << name << " " |
126 | << dlerror(); |
127 | #if defined(__hexagon__) |
128 | int p; |
129 | int rc = dlinfo(lib_handle_, RTLD_DI_LOAD_ADDR, &p); |
130 | if (rc) |
131 | FARF(ERROR, "error getting model .so start address : %u" , rc); |
132 | else |
133 | FARF(ALWAYS, "Model .so Start Address : %x" , p); |
134 | #endif |
135 | } |
136 | |
137 | void* DSOLibrary::GetSymbol_(const char* name) { return dlsym(lib_handle_, name); } |
138 | |
139 | void DSOLibrary::Unload() { |
140 | dlclose(lib_handle_); |
141 | lib_handle_ = nullptr; |
142 | } |
143 | |
144 | #endif |
145 | |
146 | ObjectPtr<Library> CreateDSOLibraryObject(std::string library_path) { |
147 | auto n = make_object<DSOLibrary>(); |
148 | n->Init(library_path); |
149 | return n; |
150 | } |
151 | } // namespace runtime |
152 | } // namespace tvm |
153 | |