Skip to content

Commit 9110dd6

Browse files
authored
Merge branch 'main' into cuda-quiet-symbol-promotion
2 parents a83f0e1 + 9bf80eb commit 9110dd6

6 files changed

Lines changed: 51 additions & 9 deletions

File tree

‎.ci/scripts/wheel/test_cuda_linux.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,27 @@ def test_cuda_libraries_resolve_relatively() -> None:
143143
print(f"✓ {name} resolves the CUDA runtime relatively ({relative[0]})")
144144

145145

146+
def test_no_library_needs_cuda_torch() -> None:
147+
"""No shipped library may record a dependency on PyTorch's own CUDA libraries.
148+
149+
The CUDA delegate needs only the CUDA runtime. A library that names libtorch_cuda or
150+
libc10_cuda cannot load next to a CPU-only torch, so the whole wheel then fails to import
151+
there even though nothing in it calls into those libraries.
152+
"""
153+
package_dir = _package_dir()
154+
cuda_torch = {"libtorch_cuda.so", "libc10_cuda.so"}
155+
offenders = {}
156+
for library in test_shared_libraries._shipped_shared_objects(package_dir):
157+
needed = test_shared_libraries._recorded_dependencies(library) & cuda_torch
158+
if needed:
159+
offenders[str(library.relative_to(package_dir))] = sorted(needed)
160+
assert not offenders, (
161+
f"these libraries depend on PyTorch's CUDA libraries, so the wheel cannot be imported "
162+
f"with a CPU-only torch: {offenders}"
163+
)
164+
print("✓ no shipped library depends on PyTorch's CUDA libraries")
165+
166+
146167
def _row_architectures() -> list[str]:
147168
"""The architectures this row claims, from the same script the build uses.
148169
@@ -586,6 +607,7 @@ def test_a_model_runs_through_the_delegate() -> None:
586607
test_cuda_libraries_are_shipped()
587608
test_cuda_runtime_is_declared()
588609
test_cuda_libraries_resolve_relatively()
610+
test_no_library_needs_cuda_torch()
589611
test_device_code_covers_the_row()
590612
test_portable_device_code_is_present()
591613
test_the_delegate_registers()

‎CMakeLists.txt‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,11 +1450,16 @@ if(EXECUTORCH_BUILD_PYBIND)
14501450
aten_bridge PUBLIC C10_USING_CUSTOM_GENERATED_MACROS
14511451
)
14521452
target_compile_options(aten_bridge PUBLIC ${_pybind_compile_options})
1453+
# torch_cpu_library is the CPU half of torch. Linking torch would also force
1454+
# libtorch_cuda into DT_NEEDED in a CUDA build, and a CPU-only torch could
1455+
# then not load this library.
14531456
if(EXECUTORCH_BUILD_SHARED)
1454-
target_link_libraries(aten_bridge PRIVATE torch c10 executorch_shared)
1457+
target_link_libraries(
1458+
aten_bridge PRIVATE torch_cpu_library c10 executorch_shared
1459+
)
14551460
else()
14561461
target_link_libraries(
1457-
aten_bridge PRIVATE torch c10 executorch extension_tensor
1462+
aten_bridge PRIVATE torch_cpu_library c10 executorch extension_tensor
14581463
)
14591464
endif()
14601465
endif()

‎extension/llm/custom_ops/CMakeLists.txt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,11 @@ if(EXECUTORCH_BUILD_KERNELS_LLM_AOT)
230230
endif()
231231
executorch_target_link_shared_runtime(custom_ops_aot_lib)
232232

233+
# torch_cpu_library is the CPU half of torch. Linking torch would also force
234+
# libtorch_cuda into DT_NEEDED in a CUDA build, and a CPU-only torch could
235+
# then not load this library.
233236
target_link_libraries(
234-
custom_ops_aot_lib PUBLIC cpublas torch extension_tensor
237+
custom_ops_aot_lib PUBLIC cpublas torch_cpu_library extension_tensor
235238
extension_threadpool
236239
)
237240
if(EXECUTORCH_BUILD_KERNELS_LLM_QUANTIZED_MOE_OPTIMIZED)

‎extension/llm/runner/CMakeLists.txt‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,14 @@ if(EXECUTORCH_BUILD_PYBIND)
120120
find_library(
121121
TORCH_PYTHON_LIBRARY torch_python PATHS "${TORCH_INSTALL_PREFIX}/lib"
122122
)
123-
# Link with the extension_llm_runner library and its dependencies
123+
# Link with the extension_llm_runner library and its dependencies.
124+
#
125+
# torch_cpu_library is the CPU half of torch. Linking torch would also force
126+
# libtorch_cuda into DT_NEEDED in a CUDA build, and a CPU-only torch could
127+
# then not load this library.
124128
target_link_libraries(
125129
_llm_runner PRIVATE extension_llm_runner tokenizers::tokenizers
126-
portable_lib ${TORCH_PYTHON_LIBRARY} ${TORCH_LIBRARIES}
130+
portable_lib ${TORCH_PYTHON_LIBRARY} torch_cpu_library
127131
)
128132
executorch_target_link_shared_runtime(_llm_runner)
129133

‎extension/training/CMakeLists.txt‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,18 @@ if(EXECUTORCH_BUILD_PYBIND)
5252
# Pybind library. When the consolidated shared runtime is built, the runtime
5353
# is resolved from it rather than from the whole-archive-forcing static
5454
# `executorch` target, so this module shares the one backend registry.
55+
#
56+
# torch_cpu_library is the CPU half of torch. Linking torch would also force
57+
# libtorch_cuda into DT_NEEDED in a CUDA build, and a CPU-only torch could
58+
# then not load this library.
5559
if(EXECUTORCH_BUILD_SHARED)
5660
set(_pybind_training_dep_libs ${TORCH_PYTHON_LIBRARY} etdump aten_bridge
57-
torch extension_training
61+
torch_cpu_library extension_training
5862
)
5963
else()
60-
set(_pybind_training_dep_libs ${TORCH_PYTHON_LIBRARY} etdump executorch
61-
aten_bridge torch extension_training
64+
set(_pybind_training_dep_libs
65+
${TORCH_PYTHON_LIBRARY} etdump executorch aten_bridge torch_cpu_library
66+
extension_training
6267
)
6368
endif()
6469

‎tools/cmake/Codegen.cmake‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,10 @@ function(gen_custom_ops_aot_lib)
334334
set_target_properties(${GEN_LIB_NAME} PROPERTIES CXX_STANDARD 20)
335335
target_compile_definitions(${GEN_LIB_NAME} PRIVATE USE_ATEN_LIB=1)
336336
include_directories(${TORCH_INCLUDE_DIRS})
337-
target_link_libraries(${GEN_LIB_NAME} PRIVATE torch)
337+
# torch_cpu_library is the CPU half of torch. Linking torch would also force
338+
# libtorch_cuda into DT_NEEDED in a CUDA build, and a CPU-only torch could
339+
# then not load this library.
340+
target_link_libraries(${GEN_LIB_NAME} PRIVATE torch_cpu_library)
338341

339342
executorch_target_link_options_shared_lib(${GEN_LIB_NAME})
340343
if(TARGET portable_lib)

0 commit comments

Comments
 (0)