Skip to content

Commit 87b7e52

Browse files
AxelNounclaude
andcommitted
Merge viable/strict (a90db24) dans fix/muse-glimmer-pos-emb-contiguous
Récupère pytorch#24050 et pytorch#24137, qui réparent unittest-cuda-muse-glimmer-batching et test-muse-glimmer-cuda-e2e-kquant-17gb-solo-text-batching, rouges sur main à la base précédente de la PR (d1f7f1f). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents c0278d2 + a90db24 commit 87b7e52

221 files changed

Lines changed: 9877 additions & 960 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.ci/scripts/setup-openvino.sh‎

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,27 @@ for arg in "$@"; do
1818
esac
1919
done
2020

21-
# Download and install OpenVINO from release packages
22-
OPENVINO_VERSION="2026.0"
23-
OPENVINO_BUILD="2026.0.0.20965.c6d6a13a886"
24-
OPENVINO_STABLE_URL="https://storage.openvinotoolkit.org/repositories/openvino/packages/${OPENVINO_VERSION}/linux/openvino_toolkit_ubuntu22_${OPENVINO_BUILD}_x86_64.tgz"
25-
26-
OPENVINO_NIGHTLY_BUILD_ID="2026.1.0-21310-c694fbc2b6d"
27-
OPENVINO_NIGHTLY_BUILD="2026.1.0.dev20260312"
28-
OPENVINO_NIGHTLY_URL="https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/${OPENVINO_NIGHTLY_BUILD_ID}/openvino_toolkit_ubuntu22_${OPENVINO_NIGHTLY_BUILD}_x86_64.tgz"
29-
21+
OPENVINO_PACKAGES_URL="https://storage.openvinotoolkit.org/repositories/openvino/packages"
3022
if [ "${USE_NIGHTLY}" = true ]; then
31-
OPENVINO_URL="${OPENVINO_NIGHTLY_URL}"
32-
OPENVINO_EXTRACTED_DIR="openvino_toolkit_ubuntu22_${OPENVINO_NIGHTLY_BUILD}_x86_64"
33-
echo "Using OpenVINO nightly build: ${OPENVINO_NIGHTLY_BUILD_ID}"
23+
# Only for quick testing. OpenVINO deletes nightlies after a few months, so
24+
# take the newest one instead of pinning a build that will disappear.
25+
OPENVINO_URL=$(curl -fsSL --retry 3 --retry-all-errors "${OPENVINO_PACKAGES_URL}/nightly/latest.txt" | sed -n 's/^ubuntu22_x86_64://p')
26+
: "${OPENVINO_URL:?could not get the ubuntu22_x86_64 nightly from latest.txt}"
27+
OPENVINO_SHA256=$(curl -fsSL --retry 3 --retry-all-errors "${OPENVINO_URL}.sha256" | sed -nE 's/^([0-9a-f]{64}).*/\1/p')
28+
: "${OPENVINO_SHA256:?could not get the SHA-256 of the nightly from its .sha256 file}"
3429
else
35-
OPENVINO_URL="${OPENVINO_STABLE_URL}"
36-
OPENVINO_EXTRACTED_DIR="openvino_toolkit_ubuntu22_${OPENVINO_BUILD}_x86_64"
37-
echo "Using OpenVINO stable release: ${OPENVINO_BUILD}"
30+
OPENVINO_VERSION="2026.4.1"
31+
OPENVINO_BUILD="2026.4.1.22982.07f9c262b05"
32+
OPENVINO_SHA256="e2541afe65a81d5aabe981f9a86ad2c7efe557922b71e5649b6aafffec7c982b"
33+
OPENVINO_URL="${OPENVINO_PACKAGES_URL}/${OPENVINO_VERSION}/linux/openvino_toolkit_ubuntu22_${OPENVINO_BUILD}_x86_64.tgz"
3834
fi
35+
OPENVINO_EXTRACTED_DIR=$(basename "${OPENVINO_URL}" .tgz)
36+
echo "Using OpenVINO: ${OPENVINO_EXTRACTED_DIR}"
3937

40-
curl -Lo /tmp/openvino_toolkit.tgz --retry 3 --retry-all-errors --fail ${OPENVINO_URL}
38+
curl -Lo /tmp/openvino_toolkit.tgz --retry 3 --retry-all-errors --fail "${OPENVINO_URL}"
39+
# The storage server answers a missing file with an HTML page and HTTP 200, so
40+
# compare the download with the expected hash before extracting it.
41+
echo "${OPENVINO_SHA256} /tmp/openvino_toolkit.tgz" | sha256sum -c -
4142
tar -xzf /tmp/openvino_toolkit.tgz
4243
mv "${OPENVINO_EXTRACTED_DIR}" openvino
4344

‎.ci/scripts/setup-qnn-deps.sh‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ set -ex
99

1010
source "$(dirname "${BASH_SOURCE[0]}")/../../backends/qualcomm/scripts/install_qnn_sdk.sh"
1111

12-
setup_libcpp 12
1312
setup_android_ndk
1413
install_qnn
1514
pip install -r backends/qualcomm/requirements.txt

‎.ci/scripts/test_backend.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fi
119119

120120
if [[ "$FLOW" == *openvino* ]]; then
121121
# Setup OpenVINO environment
122-
source .ci/scripts/setup-openvino.sh --nightly
122+
source .ci/scripts/setup-openvino.sh
123123
EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_OPENVINO=ON"
124124
fi
125125

‎.ci/scripts/test_cuda_runtime_windows.ps1‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ $tests = @(
3333
"test_cuda_allocator",
3434
"test_cuda_mutable_state",
3535
"test_cuda_weight_cache",
36+
"test_cuda_output_copy",
3637
"test_cuda_sort_rand",
3738
"test_cuda_guard",
3839
"test_cuda_stream_guard"

‎.ci/scripts/test_model_e2e.sh‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ if [ "$DEVICE" = "cuda" ] && [ "$MODEL_NAME" = "muse_glimmer" ] && [ "$MODE" = "
618618
--mode requests --requests 5 --prompt_tokens 600 --max_new_tokens 64 --stagger_ms 200
619619

620620
pip install -r examples/llm_server/python/requirements.txt
621-
python -c "from huggingface_hub import hf_hub_download; [hf_hub_download('${HF_MODEL}', f, local_dir='${MODEL_DIR}') for f in ('tokenizer_config.json', 'chat_template.jinja')]"
621+
for f in tokenizer_config.json chat_template.jinja; do
622+
curl -fL --retry 3 --retry-all-errors "$TOKENIZER_URL/$f" -o "$MODEL_DIR/$f"
623+
done
622624
PORT=$(python - <<'PY'
623625
import socket
624626

‎.ci/scripts/test_yolo26.sh‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ if [[ "${MODE}" =~ .*openvino.* ]]; then
7676
OPENVINO=ON
7777
TARGET_LIBS="$TARGET_LIBS openvino_backend "
7878

79-
# Install specific OpenVINO runtime from pip.
80-
$PYTHON_EXECUTABLE -m pip install --pre openvino==2026.1.0.dev20260131 --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
79+
$PYTHON_EXECUTABLE -m pip install openvino==2026.4.1
8180
$PYTHON_EXECUTABLE -m pip install -r backends/openvino/requirements.txt
8281

8382
# Set OPENVINO_LIB_PATH so the C++ demo runner can also find libopenvino_c.so.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
import importlib.util
8+
import json
9+
import shlex
10+
import shutil
11+
import subprocess
12+
import sys
13+
import tempfile
14+
import unittest
15+
from pathlib import Path
16+
17+
ROOT = Path(__file__).resolve().parents[3]
18+
19+
20+
def _compile_flags(entry: dict) -> set:
21+
"""The flags of one compile command, without the compiler, source and outputs."""
22+
flags = set()
23+
arguments = iter(shlex.split(entry["command"])[1:])
24+
for argument in arguments:
25+
if argument in ("-o", "-c", "-MT", "-MF"):
26+
next(arguments)
27+
elif argument == "-isystem":
28+
flags.add(f"-isystem {next(arguments)}")
29+
elif argument != "-MD":
30+
flags.add(argument)
31+
return flags
32+
33+
34+
def _copied_from_torch(flag: str) -> bool:
35+
"""Whether a flag comes from what find_package_torch copies from torch.
36+
37+
A CUDA build of torch also gives torch the CUDA toolkit include dir and torch_cuda's
38+
definitions, which torch_cpu_library correctly does not carry.
39+
"""
40+
return (
41+
flag == "-DET_TORCH_CXX_FLAGS_PROBE"
42+
or flag.startswith("-std=")
43+
or (flag.startswith("-isystem ") and flag.endswith("torch/csrc/api/include"))
44+
)
45+
46+
47+
@unittest.skipIf(sys.platform == "win32", "Visual Studio writes no compile commands")
48+
class TestTorchCpuLibraryCMake(unittest.TestCase):
49+
def test_torch_cpu_library_gets_torch_settings(self):
50+
cmake = shutil.which("cmake")
51+
if cmake is None or importlib.util.find_spec("torch") is None:
52+
self.skipTest("CMake and torch are required")
53+
54+
found_first = (
55+
"add_torch_to_cmake_prefix_path()\nfind_package(Torch CONFIG REQUIRED)"
56+
)
57+
for find_torch in ("", found_first):
58+
with self.subTest(found_first=bool(find_torch)):
59+
self._check(cmake, find_torch)
60+
61+
def _check(self, cmake: str, find_torch: str) -> None:
62+
with tempfile.TemporaryDirectory() as directory:
63+
source = Path(directory)
64+
build = source / "build"
65+
(source / "probe.cpp").write_text("int probe() { return 0; }\n")
66+
(source / "CMakeLists.txt").write_text(
67+
f"""cmake_minimum_required(VERSION 3.24)
68+
project(TorchCpuLibraryProbe LANGUAGES CXX)
69+
include("${{EXECUTORCH_ROOT}}/tools/cmake/Utils.cmake")
70+
{find_torch}
71+
find_package_torch()
72+
add_library(links_torch OBJECT probe.cpp)
73+
target_link_libraries(links_torch PRIVATE torch)
74+
add_library(links_torch_cpu_library OBJECT probe.cpp)
75+
target_link_libraries(links_torch_cpu_library PRIVATE torch_cpu_library)
76+
add_library(links_it_publicly STATIC probe.cpp)
77+
target_link_libraries(links_it_publicly PUBLIC torch_cpu_library)
78+
add_library(consumer OBJECT probe.cpp)
79+
target_link_libraries(consumer PRIVATE links_it_publicly)
80+
"""
81+
)
82+
result = subprocess.run(
83+
[
84+
cmake,
85+
"-S",
86+
str(source),
87+
"-B",
88+
str(build),
89+
f"-DEXECUTORCH_ROOT={ROOT}",
90+
f"-DPYTHON_EXECUTABLE={sys.executable}",
91+
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
92+
# Recent torch sets no TORCH_CXX_FLAGS, so set one to check it travels too.
93+
"-DTORCH_CXX_FLAGS=-DET_TORCH_CXX_FLAGS_PROBE",
94+
],
95+
capture_output=True,
96+
text=True,
97+
)
98+
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
99+
100+
flags = {}
101+
for entry in json.loads((build / "compile_commands.json").read_text()):
102+
target = Path(entry["output"]).parent.name.removesuffix(".dir")
103+
flags[target] = _compile_flags(entry)
104+
expected = {
105+
flag for flag in flags["links_torch"] if _copied_from_torch(flag)
106+
}
107+
self.assertIn("-DET_TORCH_CXX_FLAGS_PROBE", expected)
108+
self.assertTrue(any(flag.startswith("-isystem ") for flag in expected))
109+
for target in ("links_torch_cpu_library", "links_it_publicly", "consumer"):
110+
self.assertEqual(expected - flags[target], set(), target)
111+
112+
def test_find_package_torch_without_torch_cpu_library(self):
113+
"""A parent project or a static libtorch can define torch alone."""
114+
cmake = shutil.which("cmake")
115+
if cmake is None:
116+
self.skipTest("CMake is required")
117+
with tempfile.TemporaryDirectory() as directory:
118+
source = Path(directory)
119+
(source / "CMakeLists.txt").write_text(
120+
"""cmake_minimum_required(VERSION 3.24)
121+
project(TorchWithoutTorchCpuLibrary LANGUAGES NONE)
122+
include("${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake")
123+
add_library(torch INTERFACE)
124+
find_package_torch()
125+
"""
126+
)
127+
result = subprocess.run(
128+
[
129+
cmake,
130+
"-S",
131+
str(source),
132+
"-B",
133+
str(source / "build"),
134+
f"-DEXECUTORCH_ROOT={ROOT}",
135+
],
136+
capture_output=True,
137+
text=True,
138+
)
139+
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
140+
141+
142+
if __name__ == "__main__":
143+
unittest.main()

‎.ci/scripts/utils.sh‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
# Copyright (c) Meta Platforms, Inc. and affiliates.
33
# All rights reserved.
4-
# Copyright 2024 Arm Limited and/or its affiliates.
4+
# Copyright 2024,2026 Arm Limited and/or its affiliates.
55
#
66
# This source code is licensed under the BSD-style license found in the
77
# LICENSE file in the root directory of this source tree.
@@ -50,8 +50,9 @@ dedupe_macos_loader_path_rpaths() {
5050
fi
5151

5252
local torch_lib_dir
53+
local python_executable=${PYTHON_EXECUTABLE:-python}
5354
pushd ..
54-
torch_lib_dir=$(python -c "import importlib.util; print(importlib.util.find_spec('torch').submodule_search_locations[0])")/lib
55+
torch_lib_dir=$("${python_executable}" -c "import importlib.util; print(importlib.util.find_spec('torch').submodule_search_locations[0])")/lib
5556
popd
5657

5758
if [[ -z "${torch_lib_dir}" || ! -d "${torch_lib_dir}" ]]; then
@@ -83,12 +84,16 @@ dedupe_macos_loader_path_rpaths() {
8384
}
8485

8586
install_domains() {
87+
local python_executable=${PYTHON_EXECUTABLE:-python}
8688
echo "Install torchvision and torchaudio"
87-
pip install --no-build-isolation --user "git+https://github.com/pytorch/audio.git@${TORCHAUDIO_VERSION}"
88-
pip install --no-build-isolation --user "git+https://github.com/pytorch/vision.git@${TORCHVISION_VERSION}"
89+
"${python_executable}" -m pip install --no-build-isolation \
90+
"git+https://github.com/pytorch/audio.git@${TORCHAUDIO_VERSION}"
91+
"${python_executable}" -m pip install --no-build-isolation \
92+
"git+https://github.com/pytorch/vision.git@${TORCHVISION_VERSION}"
8993
}
9094

9195
install_pytorch_and_domains() {
96+
local python_executable=${PYTHON_EXECUTABLE:-python}
9297
pushd .ci/docker || return
9398
TORCH_VERSION=$(cat ci_commit_pins/pytorch.txt)
9499
popd || return
@@ -101,9 +106,9 @@ install_pytorch_and_domains() {
101106

102107
local system_name=$(uname)
103108
if [[ "${system_name}" == "Darwin" ]]; then
104-
local platform=$(python -c 'import sysconfig; import platform; v=platform.mac_ver()[0].split(".")[0]; platform=sysconfig.get_platform().split("-"); platform[1]=f"{v}_0"; print("_".join(platform))')
109+
local platform=$("${python_executable}" -c 'import sysconfig; import platform; v=platform.mac_ver()[0].split(".")[0]; platform=sysconfig.get_platform().split("-"); platform[1]=f"{v}_0"; print("_".join(platform))')
105110
fi
106-
local python_version=$(python -c 'import platform; v=platform.python_version_tuple(); print(f"{v[0]}{v[1]}")')
111+
local python_version=$("${python_executable}" -c 'import platform; v=platform.python_version_tuple(); print(f"{v[0]}{v[1]}")')
107112
local torch_release=$(cat version.txt)
108113
# Download key must match the upload key below (basename of dist/*.whl,
109114
# which always carries the build's resolved +gitHASH). Branch-ref pins
@@ -118,7 +123,7 @@ install_pytorch_and_domains() {
118123
# of the Docker image
119124
local torch_wheel_not_found=0
120125
if [[ "${system_name}" == "Darwin" ]]; then
121-
pip install "${cached_torch_wheel}" || torch_wheel_not_found=1
126+
"${python_executable}" -m pip install "${cached_torch_wheel}" || torch_wheel_not_found=1
122127
else
123128
torch_wheel_not_found=1
124129
fi
@@ -138,14 +143,14 @@ install_pytorch_and_domains() {
138143
# Keep in sync with pytorch/pyproject.toml [build-system].requires.
139144
local build_venv=/tmp/pytorch-build-venv
140145
rm -rf "${build_venv}"
141-
python -m venv --system-site-packages "${build_venv}"
146+
"${python_executable}" -m venv --system-site-packages "${build_venv}"
142147
"${build_venv}/bin/pip" install build "scikit-build-core>=1.0" ninja \
143148
"packaging>=24.2" "typing-extensions>=4.10.0" pyyaml six numpy
144149
USE_DISTRIBUTED=1 "${build_venv}/bin/python" -m build --wheel --no-isolation
145150
rm -rf "${build_venv}"
146-
pip install "$(echo dist/*.whl)"
151+
"${python_executable}" -m pip install "$(echo dist/*.whl)"
147152
# A build with no BLAS succeeds silently, so check rather than assume.
148-
(cd / && python -c "
153+
(cd / && "${python_executable}" -c "
149154
import torch
150155
assert torch._C.has_lapack, 'built without LAPACK'
151156
torch.linalg.qr(torch.randn(4, 4))

‎.ci/scripts/wheel/test_clean_install.py‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,10 @@ def run_tests(work_dir: Path) -> None:
215215

216216

217217
# Reads its arguments from stdin, blocks the named modules, then imports. A blocked module
218-
# raises ModuleNotFoundError exactly as it would be absent, so the traceback shows the import
219-
# chain that wanted it.
218+
# behaves like a missing one to import and find_spec, so the traceback shows the import chain
219+
# that wanted it.
220220
_IMPORT_PROBE = """
221-
import importlib.abc, importlib.util, json, os, sys
221+
import importlib, json, os, sys
222222
223223
# Drop the working directory, which `python -c` puts first. The equivalent flag, -P, is only
224224
# available from 3.11.
@@ -229,19 +229,23 @@ def run_tests(work_dir: Path) -> None:
229229
request = json.load(sys.stdin)
230230
blocked = set(request["blocked"])
231231
232-
233-
class _Blocker(importlib.abc.MetaPathFinder):
234-
def find_spec(self, fullname, path=None, target=None):
235-
if fullname.split(".")[0] in blocked:
236-
raise ModuleNotFoundError(
237-
f"No module named {fullname!r} (not declared by the executorch wheel)",
238-
name=fullname,
239-
)
240-
return None
241-
242-
243-
sys.meta_path.insert(0, _Blocker())
244-
importlib.import_module(request["module"])
232+
# A None entry in sys.modules makes an import raise ModuleNotFoundError while
233+
# importlib.util.find_spec returns None, which is how a missing package behaves. A finder that
234+
# raises from find_spec instead breaks code that probes for optional packages, such as
235+
# torch._dynamo, which looks up hypothesis that way.
236+
for name in blocked:
237+
sys.modules[name] = None
238+
239+
try:
240+
importlib.import_module(request["module"])
241+
except ModuleNotFoundError as error:
242+
package = (error.name or "").split(".")[0]
243+
if package in blocked:
244+
raise ModuleNotFoundError(
245+
f"No module named {package!r} (not declared by the executorch wheel)",
246+
name=package,
247+
) from error
248+
raise
245249
"""
246250

247251

0 commit comments

Comments
 (0)