This repository has been archived by the owner on Aug 16, 2024. It is now read-only.
forked from pytorch/pytorch
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[torch deploy] add support for Python C extension modules (pytorch#58117
) Summary: Pull Request resolved: pytorch#58117 Previously it was not possible to load C extension modules with deploy because extension modules need to link against the Python.h API functions. Since each libtorchdeploy_interpreter.so had its own copy of these functions, it is not possible to tell dlopen to resolve symbols in a loaded SO from one of these libraries without exposing its symbols globally. This patch adds a custom ELF loader which does the custom loading of attaching c extension libraries to the Python API that loaded the shared library. Simple use of numpy and regex modules appears to work. This diff has some limitations: * 64-bit Linux only. OSX and windows use different formats for shared libraries. 32-bit ELF files are not supported. * debug info is not immediately availiable to debuggers. A script for lldb is provided which can be loaded so that lldb knows about the libraries as they are loaded. * shared libraries can directly use the Python API, but libraries they depend on (via DT_NEEDED entries in their dynamic segment) may not use Python. In the future, we can try to detect whether a sub library uses the Python API and load it with our customer loader. * TLS initialization and library initialization may occur in a different order than what would happen with dlopen, potentially leading to some issues running destructors in TLS segments. Use of this C++ features is relatively rare. Test Plan: Imported from OSS Reviewed By: suo Differential Revision: D28435305 Pulled By: zdevito fbshipit-source-id: 10f046053dd1d250e3c73f2cce8eb945eeba31b6
- Loading branch information
1 parent
e856a45
commit 7c09de8
Showing
16 changed files
with
1,755 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import lldb # type: ignore[import] | ||
# load into lldb instance with: | ||
# command script import tools/lldb/deploy_debugger.py | ||
|
||
target = lldb.debugger.GetSelectedTarget() | ||
bp = target.BreakpointCreateByRegex("__deploy_register_code") | ||
bp.SetScriptCallbackBody("""\ | ||
process = frame.thread.GetProcess() | ||
target = process.target | ||
symbol_addr = frame.module.FindSymbol("__deploy_module_info").GetStartAddress() | ||
info_addr = symbol_addr.GetLoadAddress(target) | ||
e = lldb.SBError() | ||
ptr_size = 8 | ||
str_addr = process.ReadPointerFromMemory(info_addr, e) | ||
file_addr = process.ReadPointerFromMemory(info_addr + ptr_size, e) | ||
file_size = process.ReadPointerFromMemory(info_addr + 2*ptr_size, e) | ||
load_bias = process.ReadPointerFromMemory(info_addr + 3*ptr_size, e) | ||
name = process.ReadCStringFromMemory(str_addr, 512, e) | ||
r = process.ReadMemory(file_addr, file_size, e) | ||
from tempfile import NamedTemporaryFile | ||
from pathlib import Path | ||
stem = Path(name).stem | ||
with NamedTemporaryFile(prefix=stem, suffix='.so', delete=False) as tf: | ||
tf.write(r) | ||
print("torch_deploy registering debug inforation for ", tf.name) | ||
cmd1 = f"target modules add {tf.name}" | ||
# print(cmd1) | ||
lldb.debugger.HandleCommand(cmd1) | ||
cmd2 = f"target modules load -f {tf.name} -s {hex(load_bias)}" | ||
# print(cmd2) | ||
lldb.debugger.HandleCommand(cmd2) | ||
return False | ||
""") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
set -ex | ||
wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz | ||
tar xf openssl-1.1.1k.tar.gz | ||
(cd openssl-1.1.1k && ./config --prefix="$PYTHON_INSTALL_DIR" && make -j32 && make install) | ||
CFLAGS=-fPIC CPPFLAGS=-fPIC ./configure --prefix "$PYTHON_INSTALL_DIR" --with-openssl="$PYTHON_INSTALL_DIR" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c | ||
index c51f97abd2..83f73e351d 100644 | ||
--- a/Python/dynload_shlib.c | ||
+++ b/Python/dynload_shlib.c | ||
@@ -54,8 +54,7 @@ static struct { | ||
} handles[128]; | ||
static int nhandles = 0; | ||
|
||
- | ||
-dl_funcptr | ||
+dl_funcptr __attribute__((weak)) | ||
_PyImport_FindSharedFuncptr(const char *prefix, | ||
const char *shortname, | ||
const char *pathname, FILE *fp) |
44 changes: 44 additions & 0 deletions
44
torch/csrc/deploy/interpreter/import_find_sharedfuncptr.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include <torch/csrc/deploy/interpreter/linker.h> | ||
#include <vector> | ||
|
||
using torch::deploy::CustomLibrary; | ||
using torch::deploy::CustomLibraryPtr; | ||
using torch::deploy::SystemLibrary; | ||
|
||
// NOLINTNEXTLINE | ||
std::vector<CustomLibraryPtr> loaded_files_; | ||
// NOLINTNEXTLINE | ||
static void* deploy_self = nullptr; | ||
|
||
extern "C" { | ||
|
||
__attribute__((visibility("default"))) void deploy_set_self(void* v) { | ||
deploy_self = v; | ||
} | ||
|
||
typedef void (*dl_funcptr)(); | ||
extern "C" dl_funcptr _PyImport_FindSharedFuncptr( | ||
const char* prefix, | ||
const char* shortname, | ||
const char* pathname, | ||
FILE* fp) { | ||
const char* args[] = {"deploy"}; | ||
// XXX: we have to manually flush loaded_files_ (see deploy_flush_python_libs) | ||
// when the manager unloads. Otherwise some libraries can live longer than | ||
// they are needed, and the process of unloading them might use functionality | ||
// that itself gets unloaded. | ||
loaded_files_.emplace_back(CustomLibrary::create(pathname, 1, args)); | ||
CustomLibrary& lib = *loaded_files_.back(); | ||
lib.add_search_library(SystemLibrary::create()); | ||
lib.add_search_library(SystemLibrary::create(deploy_self)); | ||
lib.load(); | ||
std::stringstream ss; | ||
ss << prefix << "_" << shortname; | ||
auto r = (dl_funcptr)lib.sym(ss.str().c_str()).value(); | ||
assert(r); | ||
return r; | ||
} | ||
__attribute__((visibility("default"))) void deploy_flush_python_libs() { | ||
loaded_files_.clear(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.