fix(CRITICAL): bridge build delayed binding + Docker tolerance + improved preload
build_unified_bridge.sh:
- set -euo → set -eo (avoid unbound var failures)
- Drop -ltorch_cuda -lc10_cuda (unavailable at Docker build time)
- Add -Wl,--unresolved-symbols=ignore-in-shared-libs
ixformer::infer symbols resolved at runtime via RTLD_GLOBAL preload
Dockerfile Step 6:
- Wrap in (... || echo non-fatal) so Docker build continues if bridge fails
ix_unified.py:
- 3-phase preload: lib*.so → _ixformer_torch*.so → remaining .so
- All loaded with ctypes.RTLD_GLOBAL so symbols visible to bridge
- Added /workspace and /home/dylan search paths
Verified on real machine: bridge compiles (272K), undefined symbols expected
until ixformer .so preloaded at runtime by ix_unified.py
This commit is contained in:
@@ -52,9 +52,10 @@ RUN chmod +x /workspace/qwen3_6_scripts/patch_ops.sh && \
|
|||||||
bash ./patch_ops.sh 2>&1 | tee /workspace/patch_ops.log ; \
|
bash ./patch_ops.sh 2>&1 | tee /workspace/patch_ops.log ; \
|
||||||
echo "[Dockerfile] patch_ops exit code: $?"
|
echo "[Dockerfile] patch_ops exit code: $?"
|
||||||
|
|
||||||
# Step 6: Build ix_unified_bridge.so (links against base image ixformer at runtime)
|
# Step 6: Build ix_unified_bridge.so (ixformer::infer symbols resolved at runtime via RTLD_GLOBAL preload)
|
||||||
|
# Tolerant: bridge is optional — corex_moe.py has ixformer.functions fallback
|
||||||
RUN chmod +x /workspace/ex_engine/build_unified_bridge.sh && \
|
RUN chmod +x /workspace/ex_engine/build_unified_bridge.sh && \
|
||||||
bash /workspace/ex_engine/build_unified_bridge.sh 2>&1 | tee -a /workspace/ex_build.log ; \
|
(bash /workspace/ex_engine/build_unified_bridge.sh 2>&1 || echo "[Dockerfile] bridge build FAILED (non-fatal)") | tee -a /workspace/ex_build.log ; \
|
||||||
echo "[Dockerfile] ix_unified_bridge build exit code: $?"
|
echo "[Dockerfile] ix_unified_bridge build exit code: $?"
|
||||||
|
|
||||||
# Step 7: Deploy ix_unified and ex_engine Python modules to vllm path
|
# Step 7: Deploy ix_unified and ex_engine Python modules to vllm path
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# build_unified_bridge.sh — Compile ix_unified_bridge.so on BI-V100
|
# build_unified_bridge.sh — Compile ix_unified_bridge.so on BI-V100
|
||||||
# Uses manual compiler flags since torch.utils.cpp_extension is stripped from corex torch.
|
# Uses manual compiler flags since torch.utils.cpp_extension is stripped from corex torch.
|
||||||
set -euo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
SRC_DIR="${SCRIPT_DIR}/csrc/ilu"
|
SRC_DIR="${SCRIPT_DIR}/csrc/ilu"
|
||||||
@@ -34,8 +34,9 @@ $CXX -shared -fPIC -O2 -std=c++17 \
|
|||||||
-I"$TORCH_INC" \
|
-I"$TORCH_INC" \
|
||||||
-I"$TORCH_INC2" \
|
-I"$TORCH_INC2" \
|
||||||
-L"$TORCH_LIB" \
|
-L"$TORCH_LIB" \
|
||||||
-ltorch -ltorch_cpu -ltorch_cuda -lc10 -lc10_cuda \
|
-ltorch -ltorch_cpu -lc10 \
|
||||||
-Wl,--no-as-needed,-rpath,"$TORCH_LIB" \
|
-Wl,--no-as-needed,-rpath,"$TORCH_LIB" \
|
||||||
|
-Wl,--unresolved-symbols=ignore-in-shared-libs \
|
||||||
-D_GLIBCXX_USE_CXX11_ABI=0 \
|
-D_GLIBCXX_USE_CXX11_ABI=0 \
|
||||||
-DTORCH_EXTENSION_NAME=ix_unified_bridge \
|
-DTORCH_EXTENSION_NAME=ix_unified_bridge \
|
||||||
"$SRC_DIR/ix_unified_bridge.cpp" \
|
"$SRC_DIR/ix_unified_bridge.cpp" \
|
||||||
|
|||||||
@@ -30,12 +30,36 @@ def _load_bridge():
|
|||||||
if _bridge is not None:
|
if _bridge is not None:
|
||||||
return _bridge
|
return _bridge
|
||||||
|
|
||||||
# Pre-load ixformer .so symbols (bridge links against them at runtime)
|
# Pre-load ixformer .so symbols into GLOBAL symbol table.
|
||||||
|
# ix_unified_bridge.so has undefined ixformer::infer::* symbols that get
|
||||||
|
# resolved at runtime. Python default import uses RTLD_LOCAL, so we must
|
||||||
|
# force RTLD_GLOBAL on the ixformer .so files BEFORE loading our bridge.
|
||||||
try:
|
try:
|
||||||
import ctypes, glob as _glob
|
import ctypes, glob as _glob
|
||||||
|
|
||||||
for _base in ["/usr/local/corex/lib64/python3/dist-packages/ixformer",
|
for _base in ["/usr/local/corex/lib64/python3/dist-packages/ixformer",
|
||||||
"/usr/local/corex/lib/python3/dist-packages/ixformer"]:
|
"/usr/local/corex/lib/python3/dist-packages/ixformer",
|
||||||
for _so in _glob.glob(os.path.join(_base, "**/*.so"), recursive=True):
|
"/usr/local/corex/lib64"]:
|
||||||
|
if not os.path.isdir(_base):
|
||||||
|
continue
|
||||||
|
# Phase 1: lib*.so (libixformer.so, libixattn.so — dependencies first)
|
||||||
|
for _so in sorted(_glob.glob(os.path.join(_base, "lib*.so*"))):
|
||||||
|
try:
|
||||||
|
ctypes.CDLL(_so, mode=ctypes.RTLD_GLOBAL)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# Phase 2: _ixformer_torch*.so (contains ixformer::infer::* symbols)
|
||||||
|
for _so in sorted(_glob.glob(os.path.join(_base, "_ixformer_torch*.so"))):
|
||||||
|
try:
|
||||||
|
ctypes.CDLL(_so, mode=ctypes.RTLD_GLOBAL)
|
||||||
|
logger.info("Preloaded ixformer: %s", _so)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# Phase 3: any remaining .so in subdirs
|
||||||
|
for _so in sorted(_glob.glob(os.path.join(_base, "**/*.so"), recursive=True)):
|
||||||
|
bn = os.path.basename(_so)
|
||||||
|
if bn.startswith("lib") or "_ixformer" in bn:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
ctypes.CDLL(_so, mode=ctypes.RTLD_GLOBAL)
|
ctypes.CDLL(_so, mode=ctypes.RTLD_GLOBAL)
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -50,6 +74,10 @@ def _load_bridge():
|
|||||||
search_paths.append(os.path.join(here, "..", "build"))
|
search_paths.append(os.path.join(here, "..", "build"))
|
||||||
search_paths.append(here)
|
search_paths.append(here)
|
||||||
|
|
||||||
|
# 2. Workspace build dirs (Docker / real machine)
|
||||||
|
search_paths.append("/workspace/ex_engine/build")
|
||||||
|
search_paths.append("/home/dylan/project_6/ex_engine/build")
|
||||||
|
|
||||||
# 2. vllm install root (where prebuilt .so are deployed)
|
# 2. vllm install root (where prebuilt .so are deployed)
|
||||||
for p in sys.path:
|
for p in sys.path:
|
||||||
if "vllm" in p or "dist-packages" in p:
|
if "vllm" in p or "dist-packages" in p:
|
||||||
|
|||||||
Reference in New Issue
Block a user