xref: /aosp_15_r20/external/pytorch/aten/src/ATen/DynamicLibrary.cpp (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Exception.h>
2*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Unicode.h>
3*da0073e9SAndroid Build Coastguard Worker #include <ATen/DynamicLibrary.h>
4*da0073e9SAndroid Build Coastguard Worker #include <ATen/Utils.h>
5*da0073e9SAndroid Build Coastguard Worker 
6*da0073e9SAndroid Build Coastguard Worker #ifndef _WIN32
7*da0073e9SAndroid Build Coastguard Worker #include <dlfcn.h>
8*da0073e9SAndroid Build Coastguard Worker #include <libgen.h>
9*da0073e9SAndroid Build Coastguard Worker #else
10*da0073e9SAndroid Build Coastguard Worker #include <c10/util/win32-headers.h>
11*da0073e9SAndroid Build Coastguard Worker #endif
12*da0073e9SAndroid Build Coastguard Worker 
13*da0073e9SAndroid Build Coastguard Worker namespace at {
14*da0073e9SAndroid Build Coastguard Worker 
15*da0073e9SAndroid Build Coastguard Worker 
16*da0073e9SAndroid Build Coastguard Worker #ifndef C10_MOBILE
17*da0073e9SAndroid Build Coastguard Worker #ifndef _WIN32
18*da0073e9SAndroid Build Coastguard Worker 
19*da0073e9SAndroid Build Coastguard Worker // Unix
20*da0073e9SAndroid Build Coastguard Worker 
checkDL(void * x)21*da0073e9SAndroid Build Coastguard Worker static void* checkDL(void* x) {
22*da0073e9SAndroid Build Coastguard Worker   if (!x) {
23*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK_WITH(DynamicLibraryError, false, "Error in dlopen or dlsym: ", dlerror());
24*da0073e9SAndroid Build Coastguard Worker   }
25*da0073e9SAndroid Build Coastguard Worker 
26*da0073e9SAndroid Build Coastguard Worker   return x;
27*da0073e9SAndroid Build Coastguard Worker }
DynamicLibrary(const char * name,const char * alt_name,bool leak_handle_)28*da0073e9SAndroid Build Coastguard Worker DynamicLibrary::DynamicLibrary(const char* name, const char* alt_name, bool leak_handle_): leak_handle(leak_handle_), handle(dlopen(name, RTLD_LOCAL | RTLD_NOW)) {
29*da0073e9SAndroid Build Coastguard Worker   if (!handle) {
30*da0073e9SAndroid Build Coastguard Worker     if (alt_name) {
31*da0073e9SAndroid Build Coastguard Worker       handle = dlopen(alt_name, RTLD_LOCAL | RTLD_NOW);
32*da0073e9SAndroid Build Coastguard Worker       if (!handle) {
33*da0073e9SAndroid Build Coastguard Worker         TORCH_CHECK_WITH(DynamicLibraryError, false, "Error in dlopen for library ", name, "and ", alt_name);
34*da0073e9SAndroid Build Coastguard Worker       }
35*da0073e9SAndroid Build Coastguard Worker     } else {
36*da0073e9SAndroid Build Coastguard Worker       TORCH_CHECK_WITH(DynamicLibraryError, false, "Error in dlopen: ", dlerror());
37*da0073e9SAndroid Build Coastguard Worker     }
38*da0073e9SAndroid Build Coastguard Worker   }
39*da0073e9SAndroid Build Coastguard Worker }
40*da0073e9SAndroid Build Coastguard Worker 
sym(const char * name)41*da0073e9SAndroid Build Coastguard Worker void* DynamicLibrary::sym(const char* name) {
42*da0073e9SAndroid Build Coastguard Worker   AT_ASSERT(handle);
43*da0073e9SAndroid Build Coastguard Worker   return checkDL(dlsym(handle, name));
44*da0073e9SAndroid Build Coastguard Worker }
45*da0073e9SAndroid Build Coastguard Worker 
~DynamicLibrary()46*da0073e9SAndroid Build Coastguard Worker DynamicLibrary::~DynamicLibrary() {
47*da0073e9SAndroid Build Coastguard Worker   if (!handle || leak_handle) {
48*da0073e9SAndroid Build Coastguard Worker     return;
49*da0073e9SAndroid Build Coastguard Worker   }
50*da0073e9SAndroid Build Coastguard Worker   dlclose(handle);
51*da0073e9SAndroid Build Coastguard Worker }
52*da0073e9SAndroid Build Coastguard Worker 
53*da0073e9SAndroid Build Coastguard Worker #else
54*da0073e9SAndroid Build Coastguard Worker 
55*da0073e9SAndroid Build Coastguard Worker // Windows
56*da0073e9SAndroid Build Coastguard Worker 
57*da0073e9SAndroid Build Coastguard Worker DynamicLibrary::DynamicLibrary(const char* name, const char* alt_name, bool leak_handle_): leak_handle(leak_handle_) {
58*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(hicpp-signed-bitwise)
59*da0073e9SAndroid Build Coastguard Worker   HMODULE theModule;
60*da0073e9SAndroid Build Coastguard Worker   bool reload = true;
61*da0073e9SAndroid Build Coastguard Worker   auto wname = c10::u8u16(name);
62*da0073e9SAndroid Build Coastguard Worker   // Check if LOAD_LIBRARY_SEARCH_DEFAULT_DIRS is supported
63*da0073e9SAndroid Build Coastguard Worker   if (GetProcAddress(GetModuleHandleW(L"KERNEL32.DLL"), "AddDllDirectory") != NULL) {
64*da0073e9SAndroid Build Coastguard Worker     theModule = LoadLibraryExW(
65*da0073e9SAndroid Build Coastguard Worker         wname.c_str(),
66*da0073e9SAndroid Build Coastguard Worker         NULL,
67*da0073e9SAndroid Build Coastguard Worker         LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
68*da0073e9SAndroid Build Coastguard Worker     if (theModule != NULL || (GetLastError() != ERROR_MOD_NOT_FOUND)) {
69*da0073e9SAndroid Build Coastguard Worker       reload = false;
70*da0073e9SAndroid Build Coastguard Worker     }
71*da0073e9SAndroid Build Coastguard Worker   }
72*da0073e9SAndroid Build Coastguard Worker 
73*da0073e9SAndroid Build Coastguard Worker   if (reload) {
74*da0073e9SAndroid Build Coastguard Worker     theModule = LoadLibraryW(wname.c_str());
75*da0073e9SAndroid Build Coastguard Worker   }
76*da0073e9SAndroid Build Coastguard Worker 
77*da0073e9SAndroid Build Coastguard Worker   if (theModule) {
78*da0073e9SAndroid Build Coastguard Worker     handle = theModule;
79*da0073e9SAndroid Build Coastguard Worker   } else {
80*da0073e9SAndroid Build Coastguard Worker     char buf[256];
81*da0073e9SAndroid Build Coastguard Worker     DWORD dw = GetLastError();
82*da0073e9SAndroid Build Coastguard Worker     FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
83*da0073e9SAndroid Build Coastguard Worker                   NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
84*da0073e9SAndroid Build Coastguard Worker                   buf, (sizeof(buf) / sizeof(char)), NULL);
85*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK_WITH(DynamicLibraryError, false, "error in LoadLibrary for ", name, ". WinError ", dw, ": ", buf);
86*da0073e9SAndroid Build Coastguard Worker   }
87*da0073e9SAndroid Build Coastguard Worker }
88*da0073e9SAndroid Build Coastguard Worker 
89*da0073e9SAndroid Build Coastguard Worker void* DynamicLibrary::sym(const char* name) {
90*da0073e9SAndroid Build Coastguard Worker   AT_ASSERT(handle);
91*da0073e9SAndroid Build Coastguard Worker   FARPROC procAddress = GetProcAddress((HMODULE)handle, name);
92*da0073e9SAndroid Build Coastguard Worker   if (!procAddress) {
93*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK_WITH(DynamicLibraryError, false, "error in GetProcAddress");
94*da0073e9SAndroid Build Coastguard Worker   }
95*da0073e9SAndroid Build Coastguard Worker   return (void*)procAddress;
96*da0073e9SAndroid Build Coastguard Worker }
97*da0073e9SAndroid Build Coastguard Worker 
98*da0073e9SAndroid Build Coastguard Worker DynamicLibrary::~DynamicLibrary() {
99*da0073e9SAndroid Build Coastguard Worker   if (!handle || leak_handle) {
100*da0073e9SAndroid Build Coastguard Worker     return;
101*da0073e9SAndroid Build Coastguard Worker   }
102*da0073e9SAndroid Build Coastguard Worker   FreeLibrary((HMODULE)handle);
103*da0073e9SAndroid Build Coastguard Worker }
104*da0073e9SAndroid Build Coastguard Worker 
105*da0073e9SAndroid Build Coastguard Worker #endif
106*da0073e9SAndroid Build Coastguard Worker #endif
107*da0073e9SAndroid Build Coastguard Worker 
108*da0073e9SAndroid Build Coastguard Worker } // namespace at
109