Skip to content

[executorch][native-ggml] Support GGUF Q6_K PackedQuant weights - #23762

Merged
meta-codesync[bot] merged 4 commits into
gh/digantdesai/153/basefrom
gh/digantdesai/153/head
Oct 14, 2026
Merged

meta-codesync[bot] merged 4 commits into
gh/digantdesai/153/basefrom
gh/digantdesai/153/head

Conversation

@digantdesai

@digantdesai digantdesai commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Stack from ghstack (oldest at bottom):

GGUF Q4_K_M checkpoints store some weights, such as the token embedding and some projections, as Q6_K, which the ggml engine did not accept.

The ggml engine accepts GGUF Q6_K weights next to Q4_K and runs them on ggml's own Q6_K kernels, checking the block layout at load.

Authored with Claude and Codex assistance.

Differential Revision: D123796929

[ghstack-poisoned]
@pytorch-bot

pytorch-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

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

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

❌ 1 Cancelled Job, 1 Unrelated Failure

As of commit 2142395 with merge base 0a4a05e (image):

CANCELLED JOB - The following job was cancelled. Please retry:

FLAKY - The following job failed but was likely due to flakiness present on trunk:

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

@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@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 Oct 13, 2026
This was referenced Oct 13, 2026
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…out an extra copy

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* __->__ #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

Loading ggml engine constants copied each one twice, raising load time and peak memory, especially for fp32 models on CPU and quantized Llama.

The ggml engine loads constants with fewer copies, reading the package's own bytes where it can, and reports how many bytes still needed a heap copy.

Authored with Claude and Codex assistance.

Differential Revision: D123796927

Pull Request resolved: #23760
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* __->__ #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

Every execute on the ggml engine rebuilt, scheduled and allocated its graph, even when the input shapes matched the previous call, as in LLM decode.

The ggml engine keeps a configurable number of built graphs per executable, keyed by input shapes, and replays them with fresh input bytes. Row indices that feed gathers and cache writes are rechecked on every replay.

Authored with Claude and Codex assistance.

Differential Revision: D123796928

Pull Request resolved: #23761
@meta-codesync
meta-codesync Bot merged commit fb9282a into gh/digantdesai/153/base Oct 14, 2026
210 of 211 checks passed
@meta-codesync
meta-codesync Bot deleted the gh/digantdesai/153/head branch October 14, 2026 17:51
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…oss ops

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* __->__ #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

An HF static-cache Llama passes one mask and one set of cache positions to every layer, and the ggml lowering rebuilt the same conversions for each consumer.

The ggml engine reuses integer casts of immutable values and converted attention masks across ops, and invalidates them on any in-place write to their storage. An engine option prints each built graph's op counts, so tests can check that a rewrite fired.

Authored with Claude and Codex assistance.

Differential Revision: D123796930

Pull Request resolved: #23763
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* __->__ #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

Exported Llama MLPs spell `silu(gate) * up` with `aten.silu` or as `gate * sigmoid(gate) * up`. Lowered literally, that costs several elementwise kernels per layer and misses ggml's fused paths.

The ggml engine recognizes these SiLU and SwiGLU spellings from the arithmetic alone and runs them as single ggml ops. Broadcasting products are left as they are.

Authored with Claude and Codex assistance.

Differential Revision: D123796931

Pull Request resolved: #23764
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* __->__ #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The ggml lowering materialized every copying op, including permutes of size-1 axes, clones and same-type casts of contiguous tensors, which adds a kernel per copy at every decode step.

A copy of contiguous storage that is neither persistent nor written in place now shares that storage. Copies that a later in-place write could observe stay real copies.

Authored with Claude and Codex assistance.

Differential Revision: D123796932

Pull Request resolved: #23765
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* __->__ #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

With an FP16 KV cache, every K and V cache write ran a separate F32-to-F16 cast kernel before the write.

FP16 cache writes of freshly cast F32 values no longer run a separate cast, with bit-identical results. Sources that could change before the write keep their cast.

Authored with Claude and Codex assistance.

Differential Revision: D123796933

Pull Request resolved: #23766
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* __->__ #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

Each call downloaded every output into pageable host memory, which GPU drivers bounce through their own pinned buffer.

Outputs are staged in one reusable area per executable, pinned when the device offers pinned host memory. Changing inputs or a failed call now invalidates staged outputs, so a stale output cannot be read.

Authored with Claude and Codex assistance.

Differential Revision: D123796934

Pull Request resolved: #23767
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* __->__ #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

A PTN is meant to run unchanged on every native engine, but nothing checked that one exported PTN gives the same answers on each engine.

Adds an end-to-end test that exports each model, runs it on the ggml and Vulkan engines, and compares both with eager PyTorch: MobileNetV2 and a tiny HuggingFace Llama with float and GGUF weights, plus an FP16 KV cache on ggml only (native-vk's HF attention lowering needs FP32 caches). The test runners now share one engine-neutral driver.

Authored with Claude and Codex assistance.

Differential Revision: D123796936

Pull Request resolved: #23768
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…engines

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* __->__ #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The same Llama app existed twice, once per engine, and the copies had already drifted. Every app fix had to be made twice, and more engines are coming.

Adds one engine-neutral decoder-only LLM runner next to the HuggingFace exporter, with a few-line front end per engine (Vulkan, ggml CPU/CUDA/HIP), and removes the two copies. The Vulkan runner now reports decode per step and stops at the KV-cache length, as the ggml one did.

Authored with Claude and Codex assistance.

Differential Revision: D123796942

Pull Request resolved: #23769
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…eads

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* __->__ #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The Vulkan engine runs functional in-place ops such as `relu_` out of place, and refused any whose input was a view. So a ReLU after a reshape, which the native passes emit, could not compile.

In-place ops whose input is a view now run out of place when nothing else reads the view or anything up its alias chain. They are still refused when something else does.

Authored with Claude and Codex assistance.

Differential Revision: D124032906

Pull Request resolved: #23770
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* __->__ #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ET-VK views keep the sizes they were built with, so the Vulkan engine rejected any view of a dynamically shaped source other than `aten.view`. Models that split heads or build masks over a dynamic sequence stopped at compile.

Views of dynamically shaped sources (permute, select, squeeze, unsqueeze, alias) now run as copy kernels that follow resizes. They keep their source's layout, and negative dims are supported.

Authored with Claude and Codex assistance.

Differential Revision: D124032907

Pull Request resolved: #23771
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…d layout

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* __->__ #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ET-VK's layer norm requires its input and output to share a packed layout, but layout assignment could give them different ones, so a layer norm of a graph input feeding a linear failed at compile.

Layer norm keeps its input and output in one packed layout, like the elementwise ops, with no extra copy.

Authored with Claude and Codex assistance.

Differential Revision: D124032908

Pull Request resolved: #23772
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* __->__ #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The native passes emit GELU and sigmoid after a linear as in-place ops, which the Vulkan engine did not map, so they failed as unsupported.

`gelu_` and `sigmoid_` run out of place like `relu_`, with the same refusal when their input is read elsewhere.

Authored with Claude and Codex assistance.

Differential Revision: D124032909

Pull Request resolved: #23773
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* __->__ #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ET-VK's convolution reads and writes only channels-packed textures, but a convolution between linears could be given width-packed activations, so compile failed.

The Vulkan engine converts a convolution's input and output to the layout the kernel needs. It refuses a transposed 1D convolution, which ET-VK would otherwise run as a forward one.

Authored with Claude and Codex assistance.

Differential Revision: D124032910

Pull Request resolved: #23774
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* __->__ #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

After a dynamic resize shrinks a conv1d's input, its texture is longer than the input, so padding taps read stale texels from an earlier, longer run and the last output frames were wrong.

The conv1d shader reads zeros for taps outside the input's logical length.

Authored with Claude and Codex assistance.


cc @SS-JIA @manuelcandales @cbilgin

Differential Revision: D124032911

Pull Request resolved: #23775
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…packed layout

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* __->__ #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ET-VK's pad picks its shader by the output's layout alone, so when layout assignment gave its input another layout, as in pad -> reshape -> linear, results were silently wrong.

Pad's input and output always share one packed layout, so pad is correct whatever layout layout assignment picks for either side.

Authored with Claude and Codex assistance.

Differential Revision: D124032912

Pull Request resolved: #23776
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…g, lt and conv1d

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* __->__ #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The ggml diffs above this one, and the speech encoders they serve, need ops the ggml engine did not lower.

The ggml engine lowers layer norm over the last dim (F32 only), GELU in both forms, log, in-place sigmoid, zero constant padding, less-than and 1D convolution. It also accepts an attention mask with a single query row. The cross-engine tests that skipped ggml for these ops now run on both engines.

Authored with Claude and Codex assistance.

Differential Revision: D124165055

Pull Request resolved: #23777
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* __->__ #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

HuggingFace attention transposes q, k and v to head-major and back, and the ggml lowering copied every such permutation, adding copy kernels per attention layer on every step.

Permutations of storage the graph never writes stay strided views. Ops that can read strides consume them directly, and any other reader gets one shared copy.

Authored with Claude and Codex assistance.

Differential Revision: D124020049

Pull Request resolved: #23778
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* __->__ #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

With an FP16 KV cache, the exported query is cast to F16 to match the cache, and the ggml lowering cast it back to F32 for attention, adding two copy kernels per attention.

Attention reads the query's F32 source directly, which gives the same result because ggml's attention rounds the query itself. A source that could change before the read keeps its cast.

Authored with Claude and Codex assistance.

Differential Revision: D124020051

Pull Request resolved: #23779
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* #23781
* __->__ #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

A static-cache LLM attends its whole cache on every step, though the causal mask hides the keys past the current position, so most attention work at long contexts goes to masked keys.

When an attention mask hides every key past the query positions, the ggml engine attends only the key prefix some query can see, and keeps replaying cached graphs as that prefix grows.

Authored with Claude and Codex assistance.

Differential Revision: D124020057

Pull Request resolved: #23780
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* #23782
* __->__ #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

Batch norm recomputed its scale and shift from constant statistics on every call, about seven ggml ops per norm.

Batch norms with constant statistics fold to a precomputed scale and shift at load. A convolution whose output and weight nothing else reads absorbs its batch norm entirely. The PTN is unchanged.

Authored with Claude and Codex assistance.

Differential Revision: D124020059

Pull Request resolved: #23781
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* #23783
* __->__ #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ggml's im2col can be inefficient for 1x1 convolutions on some backends; on Metal, for example, it runs one thread per threadgroup for a 1x1 kernel.

1x1 convolutions on the ggml engine no longer use per-tap im2col. Results are bit-identical, and larger kernels are unchanged.

Authored with Claude and Codex assistance.

Differential Revision: D124020060

Pull Request resolved: #23782
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
…on Metal

Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* #23784
* __->__ #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The ggml engine could run on CPU, CUDA and HIP, but had no build for Apple GPUs through ggml's Metal backend.

Adds build targets for ggml's Metal backend and an arm64 CPU backend, and Metal variants of the ggml engine and LLM runner.

Authored with Claude and Codex assistance.

Differential Revision: D124020061

Pull Request resolved: #23783
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* #23786
* __->__ #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

ggml has no integer arithmetic kernels, so an integer elementwise op, such as an int64 input plus a scalar, compiled and then aborted the ggml CPU runner.

Integer elementwise arithmetic on the ggml engine runs in F32, which holds the engine's integer values exactly up to 2^24.

Authored with Claude and Codex assistance.

Differential Revision: D124165057

Pull Request resolved: #23784
meta-codesync Bot pushed a commit that referenced this pull request Oct 14, 2026
Stack from [ghstack](https://github.com/ezyang/ghstack/tree/0.15.0) (oldest at bottom):
* __->__ #23786
* #23784
* #23783
* #23782
* #23781
* #23780
* #23779
* #23778
* #23777
* #23776
* #23775
* #23774
* #23773
* #23772
* #23771
* #23770
* #23769
* #23768
* #23767
* #23766
* #23765
* #23764
* #23763
* #23762
* #23761
* #23760
* #23759
* #23758
* #23757
* #23756
* #23755
* #23754
* #23753
* #23752
* #23751
* #23750
* #23749
* #23748
* #23747

The ggml engine was one file of over 4,000 lines holding type handling, host-integer folding, the graph builder, every op lowering and the executable, so changes and reviews meant navigating all of it.

Splits it into units for types, host integers, the graph builder and op families (elementwise, shape, linear, convolution, attention), with the executable left in `GgmlExecutor.cpp`. It is pure code motion with no behavior change.

Authored with Claude and Codex assistance.

Differential Revision: D124314780

Pull Request resolved: #23786
digantdesai added a commit that referenced this pull request Oct 14, 2026
This PR was created by the merge bot to help merge the original PR into
the main branch.
ghstack PR number: #23762 by
@digantdesai
^ Please use this as the source of truth for the PR details, comments,
and reviews
ghstack PR base:
https://github.com/pytorch/executorch/tree/gh/digantdesai/153/base
ghstack PR head:
https://github.com/pytorch/executorch/tree/gh/digantdesai/153/head
Merge bot PR base:
https://github.com/pytorch/executorch/tree/gh/digantdesai/152/orig
Merge bot PR head:
https://github.com/pytorch/executorch/tree/gh/digantdesai/153/orig
Differential Revision:
[D123796929](https://our.internmc.facebook.com/intern/diff/D123796929/)
@diff-train-skip-merge

Co-authored-by: Digant Desai <digantdesai@meta.com>

This branch had an error being deployed

1 failed and 1 active deployments
cherry-pick-bot — 2142395c Deployed Oct 14, 2026 by meta-codesync[bot] via Try to create a PR with ghstack /orig branch #1815
cadence — 2142395c Deployed Oct 14, 2026 by digantdesai via hifi-op-test / hifi4 #33336
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. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants