Skip to content

Run the Metal backend tests, which are not importable today - #22978

Closed
shoumikhin wants to merge 1 commit into
mainfrom
metal-so-dep-check
Closed

shoumikhin wants to merge 1 commit into
mainfrom
metal-so-dep-check

Conversation

@shoumikhin

@shoumikhin shoumikhin commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Reduced. The OpenMP fix has moved upstream to pytorch/pytorch#198232, which adds -dead_strip_dylibs to the link for AOTI MPS builds that do not link libtorch, per the review here. What is left in this PR is a separate defect found on the way.

backends/apple/metal/tests/test_metal_backend.py imports COMPILE_SPEC_KEYS from metal_backend, where it no longer lives. Importing the file raises, so its five tests cannot run, and pytest.ini never listed the path so nothing noticed. Take the name from aoti_backend, where it is defined, and add the file to testpaths.

The package marker goes with it. The directory has no importable content of its own, and while it is a package the module is named tests rather than something under executorch, which is a top-level name to be claiming.

What is still to do for #22955

  1. [inductor] Do not leave an unused OpenMP dependency in AOTI MPS artifacts pytorch#198232 lands.
  2. The PyTorch pin here moves to a commit that has it.
  3. ExecuTorch drops the libomp.dylib linkage and the rpaths in the Metal CMake, and the install name rewrite in run_metal_test.sh, and adds an end to end test that runs inference in a process which neither links nor preloads OpenMP.

Step 3 cannot go before step 2. Removing the runner's OpenMP while exported models still name it would pass CI here for the wrong reason, because the exporter and the runner are the same machine and the baked absolute path resolves. That is the property that let this go unnoticed in the first place.

Test plan

pytest backends/apple/metal/tests/test_metal_backend.py, 5 passed. Before this change the same command fails at collection with cannot import name 'COMPILE_SPEC_KEYS'.

Copilot AI lite review requested due to automatic review settings September 21, 2026 20:45
@pytorch-bot

pytorch-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22978

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

⏳ No Failures, 149 Pending

As of commit b2d4da5 with merge base c5d07e4 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 21, 2026
@shoumikhin shoumikhin added the release notes: apple Changes to the Apple backend delegate label Sep 21, 2026
Copilot AI review requested due to automatic review settings September 21, 2026 23:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin shoumikhin changed the title Warn at export when a compiled model needs a library the user will not have Report at export when a compiled model needs a library the user will not have Sep 21, 2026
Copilot AI review requested due to automatic review settings September 21, 2026 23:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 00:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin shoumikhin changed the title Report at export when a compiled model needs a library the user will not have Stop Metal models from depending on an OpenMP library they never call Sep 22, 2026
Copilot AI review requested due to automatic review settings September 22, 2026 02:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 04:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mergennachin
mergennachin self-requested a review September 22, 2026 05:00
Copilot AI review requested due to automatic review settings September 22, 2026 14:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 15:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mergennachin

Copy link
Copy Markdown
Contributor

The dependency diagnosis and -Wl,-dead_strip_dylibs approach look correct. I'd prefer to put the flag in Inductor's existing MPS build options, then update the PyTorch pin here. For example:

if device_type == "mps":
    definitions.append(" USE_MPS")
    if _IS_MACOS and aot_mode and not link_libtorch:
        ldflags.append("Wl,-dead_strip_dylibs")

Inductor adds the leading - and already clears ldflags for compilation, preprocessing, and header precompilation. This uses the existing build-phase handling and honors the selected compiler. The current wrapper skips the fix whenever CXX is set, even for CXX=/usr/bin/clang++.

I would also audit the explicit TORCH_OMP_LIBRARY linkage and rpaths in Metal's CMake configuration. Once we confirm the compiled runtime has no OpenMP references, those and the runner's install-name workaround should be removed; this PR currently leaves the runtime dependency in place.

For regression coverage, test upstream that an unused OpenMP dependency disappears while a referenced one remains. In ExecuTorch, export a small Metal model, assert that its embedded library has no OpenMP dependency under any install name, and run inference in a separate native executable that neither links nor preloads OpenMP.

I'd leave the generic AotiBackend.validate_so hook out of this targeted fix. The proposed check detects unwanted absolute paths, but accepting @rpath/... does not establish that a library is shipped or resolvable. A broader portability check needs a separate contract around application-provided libraries.

Review assisted by Codex.

backends/apple/metal/tests/test_metal_backend.py imports COMPILE_SPEC_KEYS
from metal_backend, where it no longer lives. Importing the file raises, so
the five tests in it cannot run, and pytest.ini never listed the path so
nothing noticed.

Take the name from aoti_backend, where it is defined, and add the file to
testpaths. The tests pass as written once they can be imported.

The package marker goes with it: the directory has no importable content of
its own, and while it is a package the module is named tests rather than
something under executorch, which is a top-level name to be claiming.
Copilot AI review requested due to automatic review settings September 22, 2026 16:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin shoumikhin changed the title Stop Metal models from depending on an OpenMP library they never call Run the Metal backend tests, which are not importable today Sep 22, 2026
@shoumikhin

Copy link
Copy Markdown
Contributor Author

You are right on all four points. I checked each one against cpp_builder before agreeing, and two of your observations are what decided it: _process_compile_only_options already empties ldflags for compile, preprocess and precompiled header steps, so a flag added there cannot reach the step that broke the wrapper, and the renderer adds the leading dash itself.

The CXX hole is real and worse than you put it. config.cpp.cxx defaults to (None, os.environ.get("CXX", ...)) and get_cpp_compiler never reads the variable separately on posix, so the compiler the wrapper would have wrapped already is their CXX. The guard turned the fix off in exactly the case where wrapping was harmless.

The flag is now upstream as pytorch/pytorch#198232, in the mps branch of get_cpp_torch_device_options, gated the way you wrote it. It carries the regression test in the shape you asked for: compile a small MPS model, read the load commands with otool -L, require that no OpenMP library appears and that libSystem still does, so the unused dependency disappearing and a referenced one surviving are both covered.

validate_so is out. An @rpath name does not establish that a library is shipped, so the check read stronger than it was, and the end to end test is better evidence.

The TORCH_OMP_LIBRARY linkage and rpaths in the Metal CMake, and the install name rewrite in run_metal_test.sh, are the remaining half. They wait for the pin to carry the upstream fix. Removing them first would take the net away while exported models still name libomp, and it would pass CI here for the wrong reason, since the exporter and the runner are the same machine and the baked path resolves. That is the property that hid this to begin with.

This PR is now reduced to something unrelated that turned up on the way: test_metal_backend.py imports COMPILE_SPEC_KEYS from metal_backend, where it no longer lives, so the file has never been importable and pytest.ini did not list it. Say the word if you would rather that went in on its own and this one just closed.

This branch was successfully deployed

1 active deployment
cadence b2d4da56 Deployed Sep 22, 2026 by shoumikhin via hifi-op-test / hifi4 #29018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. release notes: apple Changes to the Apple backend delegate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants