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:
Claude
2026-08-11 09:33:21 +00:00
parent 1d5856f4a9
commit 97d9842180
3 changed files with 37 additions and 7 deletions

View File

@@ -30,12 +30,36 @@ def _load_bridge():
if _bridge is not None:
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:
import ctypes, glob as _glob
for _base in ["/usr/local/corex/lib64/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/lib/python3/dist-packages/ixformer",
"/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:
ctypes.CDLL(_so, mode=ctypes.RTLD_GLOBAL)
except Exception:
@@ -50,6 +74,10 @@ def _load_bridge():
search_paths.append(os.path.join(here, "..", "build"))
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)
for p in sys.path:
if "vllm" in p or "dist-packages" in p: