OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RuntimeLibManager.cpp
Go to the documentation of this file.
1 #ifdef HAVE_TORCH_TFS
2 #include <torch/version.h>
3 #endif
4 
5 #include "Logger/Logger.h"
7 #include "RuntimeLibManager.h"
8 
9 #include <boost/dll/shared_library.hpp>
10 
11 #include <map>
12 #include <memory>
13 #include <unordered_map>
14 
15 boost::dll::shared_library libtorch;
16 boost::dll::shared_library libTorchTFs;
17 
19 
20 boost::filesystem::path get_torch_table_functions_path() {
21  boost::filesystem::path torch_table_functions_path{heavyai::get_root_abs_path()};
22  torch_table_functions_path /= "QueryEngine";
23  torch_table_functions_path /= "TableFunctions";
24  torch_table_functions_path /= "SystemFunctions";
25  torch_table_functions_path /= "os";
26  torch_table_functions_path /= "Torch";
27  torch_table_functions_path /= "TorchTableFunctions";
28 
29  return torch_table_functions_path;
30 }
31 
32 boost::filesystem::path get_runtime_test_lib_tfs_path() {
33  boost::filesystem::path runtime_test_lib_tfs_path{heavyai::get_root_abs_path()};
34  runtime_test_lib_tfs_path /= "QueryEngine";
35  runtime_test_lib_tfs_path /= "TableFunctions";
36  runtime_test_lib_tfs_path /= "RuntimeLibTestFunctions";
37  runtime_test_lib_tfs_path /= "RuntimeLibTestTableFunctions";
38 
39  return runtime_test_lib_tfs_path;
40 }
41 
42 boost::filesystem::path get_runtime_test_lib_path() {
43  boost::filesystem::path runtime_test_lib_path{heavyai::get_root_abs_path()};
44  runtime_test_lib_path /= "QueryEngine";
45  runtime_test_lib_path /= "TableFunctions";
46  runtime_test_lib_path /= "RuntimeLibTestFunctions";
47  runtime_test_lib_path /= "TestRuntimeLib";
48 
49  return runtime_test_lib_path;
50 }
51 
52 void RuntimeLibManager::loadRuntimeLibs(const std::string& torch_lib_path) {
53  is_libtorch_loaded_ = false;
54 #ifdef HAVE_TORCH_TFS
55  // Third party libraries must be loaded with the RTLD_GLOBAL flag set, so their symbols
56  // can be available for resolution by further dynamic loads
57  // They must also be loaded using RTLD_DEEPBIND, in case they have statically linked
58  // symbols from common libraries that conflict with symbols also statically linked with
59  // heavydb. For instance, LibTorch also statically links with LLVM, so not using
60  // RTLD_DEEPBIND will cause issues with LibTorch referring to heavy's LLVM symbols or
61  // vice-versa.
62  if (!torch_lib_path.empty()) {
63  boost::dll::fs::path lib_path(torch_lib_path);
64  libtorch = boost::dll::shared_library(
65  lib_path,
66  boost::dll::load_mode::rtld_global | boost::dll::load_mode::rtld_deepbind);
67  } else {
68  libtorch = boost::dll::shared_library("libtorch",
69  boost::dll::load_mode::search_system_folders |
70  boost::dll::load_mode::append_decorations |
71  boost::dll::load_mode::rtld_global |
72  boost::dll::load_mode::rtld_deepbind);
73  }
74 
75  if (!libtorch.is_loaded()) {
76  throw(std::runtime_error(
77  "Failed to load runtime library LibTorch. Support for library is disabled!"));
78  }
79 
80  LOG(WARNING) << "This HeavyDB was built against LibTorch version " << TORCH_VERSION
81  << ". Using a different version of LibTorch may cause breaking behavior!";
82 
83  // Shared libraries containing table function implementations must also be loaded
84  // using RTLD_GLOBAL, as the JIT-ed LLVM code needs to resolve the symbols at runtime.
85  // They must also be loaded using RTLD_DEEPBIND, which makes sure name binding favors
86  // symbols local to the library before considering global ones. This makes sure the
87  // TableFunctionsFactory::init() calls within the library call its own init() function
88  // rather than the server's main one.
89  // TODO: This behavior may not be supported in Windows, we should test symbol
90  // resolution in Windows platforms to make sure this works.
91  boost::dll::fs::path torch_tfs_lib_path(get_torch_table_functions_path());
92  libTorchTFs = boost::dll::shared_library(
93  torch_tfs_lib_path,
94  boost::dll::load_mode::rtld_lazy | boost::dll::load_mode::search_system_folders |
95  boost::dll::load_mode::rtld_global | boost::dll::load_mode::append_decorations |
96  boost::dll::load_mode::rtld_deepbind);
97  if (!libTorchTFs.is_loaded()) {
98  throw(
99  std::runtime_error("Failed to load LibTorch table function module. LibTorch "
100  "table function support is disabled!"));
101  }
102 
103  if (!libTorchTFs.has("init_table_functions")) {
104  LOG(FATAL) << "Load-time table function module does not contain "
105  "'init_table_functions' symbol!";
106  }
107 
108  // calls the module's TableFunctionsFactory::init() to register table functions
109  auto initFunction = libTorchTFs.get<void(void)>("init_table_functions");
110  initFunction();
111  is_libtorch_loaded_ = true;
112 #endif
113 }
114 
115 boost::dll::shared_library testLib;
116 boost::dll::shared_library testLibTFs;
117 
119  testLib = boost::dll::shared_library(get_runtime_test_lib_path(),
120  boost::dll::load_mode::append_decorations |
121  boost::dll::load_mode::rtld_global |
122  boost::dll::load_mode::search_system_folders |
123  boost::dll::load_mode::rtld_deepbind);
124 
125  if (!testLib.is_loaded()) {
126  throw(std::runtime_error("Failed to load test runtime library!"));
127  }
128 
129  testLibTFs = boost::dll::shared_library(
131  boost::dll::load_mode::rtld_lazy | boost::dll::load_mode::search_system_folders |
132  boost::dll::load_mode::rtld_global | boost::dll::load_mode::append_decorations |
133  boost::dll::load_mode::rtld_deepbind);
134  if (!testLibTFs.is_loaded()) {
135  throw(std::runtime_error("Failed to load test runtime library table functions!!"));
136  }
137 
138  if (!testLibTFs.has("init_table_functions")) {
139  LOG(FATAL)
140  << "Test runtime table function library has no init_table_functions symbol!";
141  }
142  auto initFunction = testLibTFs.get<void(void)>("init_table_functions");
143  initFunction();
144 }
145 
147  return is_libtorch_loaded_;
148 }
static void loadTestRuntimeLibs()
boost::filesystem::path get_runtime_test_lib_path()
std::string get_root_abs_path()
static void loadRuntimeLibs(const std::string &torch_lib_path=std::string())
#define LOG(tag)
Definition: Logger.h:285
boost::dll::shared_library testLib
static bool is_libtorch_loaded()
boost::dll::shared_library testLibTFs
boost::dll::shared_library libtorch
boost::filesystem::path get_runtime_test_lib_tfs_path()
static bool is_libtorch_loaded_
boost::filesystem::path get_torch_table_functions_path()
boost::dll::shared_library libTorchTFs