/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /*! * \file dso_libary.cc * \brief Create library module to load from dynamic shared library. */ #include #include #include #include #include "library_module.h" #if defined(_WIN32) #include #else #include #endif namespace tvm { namespace runtime { /*! * \brief Dynamic shared library object used to load * and retrieve symbols by name. This is the default * module TVM uses for host-side AOT compilation. */ class DSOLibrary final : public Library { public: ~DSOLibrary(); /*! * \brief Initialize by loading and storing * a handle to the underlying shared library. * \param name The string name/path to the * shared library over which to initialize. */ void Init(const std::string& name); /*! * \brief Returns the symbol address within * the shared library for a given symbol name. * \param name The name of the symbol. * \return The symbol. */ void* GetSymbol(const char* name) final; private: /*! \brief Private implementation of symbol lookup. * Implementation is operating system dependent. * \param The name of the symbol. * \return The symbol. */ void* GetSymbol_(const char* name); /*! \brief Implementation of shared library load. * Implementation is operating system dependent. * \param The name/path of the shared library. */ void Load(const std::string& name); /*! \brief Implementation of shared library unload. * Implementation is operating system dependent. */ void Unload(); #if defined(_WIN32) //! \brief Windows library handle HMODULE lib_handle_{nullptr}; #else // \brief Linux library handle void* lib_handle_{nullptr}; #endif }; DSOLibrary::~DSOLibrary() { if (lib_handle_) Unload(); } void DSOLibrary::Init(const std::string& name) { Load(name); } void* DSOLibrary::GetSymbol(const char* name) { return GetSymbol_(name); } #if defined(_WIN32) void* DSOLibrary::GetSymbol_(const char* name) { return reinterpret_cast(GetProcAddress(lib_handle_, (LPCSTR)name)); // NOLINT(*) } void DSOLibrary::Load(const std::string& name) { // use wstring version that is needed by LLVM. std::wstring wname(name.begin(), name.end()); lib_handle_ = LoadLibraryW(wname.c_str()); ICHECK(lib_handle_ != nullptr) << "Failed to load dynamic shared library " << name; } void DSOLibrary::Unload() { FreeLibrary(lib_handle_); lib_handle_ = nullptr; } #else void DSOLibrary::Load(const std::string& name) { lib_handle_ = dlopen(name.c_str(), RTLD_LAZY | RTLD_LOCAL); ICHECK(lib_handle_ != nullptr) << "Failed to load dynamic shared library " << name << " " << dlerror(); } void* DSOLibrary::GetSymbol_(const char* name) { return dlsym(lib_handle_, name); } void DSOLibrary::Unload() { dlclose(lib_handle_); lib_handle_ = nullptr; } #endif ObjectPtr CreateDSOLibraryObject(std::string library_path) { auto n = make_object(); n->Init(library_path); return n; } } // namespace runtime } // namespace tvm