Skip to content

Commit 2111b34

Browse files
authored
Merge branch 'main' into export-D81491136
2 parents ad9ea34 + 8607c89 commit 2111b34

File tree

237 files changed

+5629
-2148
lines changed

Some content is hidden

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

237 files changed

+5629
-2148
lines changed

.ci/scripts/setup-windows.ps1

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
param (
2+
[string]$editable = $false
3+
)
4+
5+
conda create --yes --quiet -n et python=3.12
6+
conda activate et
7+
8+
# Activate the VS environment - this is required for Dynamo to work, as it uses MSVC.
9+
# There are a bunch of environment variables that it requires.
10+
# See https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line.
11+
& "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64
12+
13+
# Install test dependencies
14+
pip install -r .ci/docker/requirements-ci.txt
15+
16+
if ($editable -eq 'true') {
17+
install_executorch.bat --editable
18+
} else {
19+
install_executorch.bat
20+
}
21+
if ($LASTEXITCODE -ne 0) {
22+
Write-Host "Installation was unsuccessful. Exit code: $LASTEXITCODE."
23+
exit $LASTEXITCODE
24+
}

.ci/scripts/test_model.ps1

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
param (
2+
[string]$modelName,
3+
[string]$backend,
4+
[string]$buildDir = "cmake-out",
5+
[bool]$strict = $false
6+
)
7+
8+
Set-PSDebug -Trace 1
9+
$ErrorActionPreference = 'Stop'
10+
$PSNativeCommandUseErrorActionPreference = $true
11+
12+
function ExportModel-Portable {
13+
param (
14+
[string]$model_name,
15+
[bool]$strict
16+
)
17+
18+
$exportParams = "--model_name", "$modelName"
19+
if ($strict) {
20+
$exportParams += "--strict"
21+
}
22+
python -m examples.portable.scripts.export @exportParams | Write-Host
23+
if ($LASTEXITCODE -ne 0) {
24+
Write-Host "Model export failed. Exit code: $LASTEXITCODE."
25+
exit $LASTEXITCODE
26+
}
27+
28+
"$modelName.pte"
29+
}
30+
31+
function ExportModel-Xnnpack {
32+
param (
33+
[string]$model_name,
34+
[bool]$quantize
35+
)
36+
37+
if $(quantize) {
38+
python -m examples.xnnpack.aot_compiler --model_name="${MODEL_NAME}" --delegate --quantize | Write-Host
39+
$modelFile = "$($modelName)_xnnpack_q8.pte"
40+
} else {
41+
python -m examples.xnnpack.aot_compiler --model_name="${MODEL_NAME}" --delegate | Write-Host
42+
$modelFile = "$($modelName)_xnnpack_fp32.pte"
43+
}
44+
if ($LASTEXITCODE -ne 0) {
45+
Write-Host "Model export failed. Exit code: $LASTEXITCODE."
46+
exit $LASTEXITCODE
47+
}
48+
49+
$modelFile
50+
}
51+
52+
# Build the runner
53+
if (Test-Path -Path $buildDir) {
54+
Remove-Item -Path $buildDir -Recurse -Force
55+
}
56+
New-Item -Path $buildDir -ItemType Directory
57+
Push-Location $buildDir
58+
cmake .. --preset windows
59+
cmake --build . -t executor_runner -j16 --config Release
60+
if ($LASTEXITCODE -ne 0) {
61+
Write-Host "Runner build failed. Exit code: $LASTEXITCODE."
62+
exit $LASTEXITCODE
63+
}
64+
$executorBinaryPath = Join-Path -Path $buildDir -ChildPath "Release\executor_runner.exe"
65+
Pop-Location
66+
67+
# Export the model
68+
switch ($backend) {
69+
"portable" {
70+
$model_path = ExportModel-Portable -model_name $modelName -strict $strict
71+
}
72+
"xnnpack-f32" {
73+
$model_path = ExportModel-Xnnpack -model_name $modelName -quantize $false
74+
}
75+
"xnnpack-q8" {
76+
$model_path = ExportModel-Xnnpack -model_name $modelName -quantize $true
77+
}
78+
default {
79+
Write-Host "Unknown backend $backend."
80+
exit 1
81+
}
82+
}
83+
84+
# Run the runner
85+
& "$executorBinaryPath" --model_path="$model_path"
86+
if ($LASTEXITCODE -ne 0) {
87+
Write-Host "Model execution failed. Exit code: $LASTEXITCODE."
88+
exit $LASTEXITCODE
89+
}

.ci/scripts/unittest-windows.ps1

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
11
param (
2-
[string]$editable
2+
[string]$editable = $false
33
)
44

55
Set-PSDebug -Trace 1
66
$ErrorActionPreference = 'Stop'
77
$PSNativeCommandUseErrorActionPreference = $true
88

9-
conda create --yes --quiet -n et python=3.12
10-
conda activate et
11-
12-
# Activate the VS environment - this is required for Dynamo to work, as it uses MSVC.
13-
# There are a bunch of environment variables that it requires.
14-
# See https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line.
15-
& "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64
16-
17-
# Install test dependencies
18-
pip install -r .ci/docker/requirements-ci.txt
19-
20-
if ($editable -eq 'true') {
21-
install_executorch.bat --editable
22-
} else {
23-
install_executorch.bat
24-
}
25-
if ($LASTEXITCODE -ne 0) {
26-
Write-Host "Installation was unsuccessful. Exit code: $LASTEXITCODE."
27-
exit $LASTEXITCODE
28-
}
29-
309
# Run pytest with coverage
3110
# pytest -n auto --cov=./ --cov-report=xml
3211
pytest -v --full-trace -c pytest-windows.ini

.github/workflows/_unittest.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,13 @@ jobs:
6363
timeout: 120
6464
script: |
6565
conda init powershell
66-
powershell .ci/scripts/unittest-windows.ps1 -editable "${{ inputs.editable }}"
66+
67+
powershell -Command "& {
68+
Set-PSDebug -Trace 1
69+
\$ErrorActionPreference = 'Stop'
70+
\$PSNativeCommandUseErrorActionPreference = \$true
71+
72+
.ci/scripts/setup-windows.ps1
73+
74+
powershell .ci/scripts/unittest-windows.ps1 -editable "${{ inputs.editable }}"
75+
}"

.github/workflows/android-perf.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
# Separate default values from the workflow dispatch. To ensure defaults are accessible
7373
# during scheduled runs and to provide flexibility for different defaults between
7474
# on-demand and periodic benchmarking.
75-
CRON_DEFAULT_MODELS: ${{ github.event_name == 'schedule' && 'mv3,mv2,ic4,ic3,resnet50,edsr,mobilebert,w2l,meta-llama/Llama-3.2-1B,meta-llama/Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8,meta-llama/Llama-3.2-1B-Instruct-QLORA_INT4_EO8,Qwen/Qwen3-0.6B,HuggingFaceTB/SmolLM2-135M,allenai/OLMo-1B-hf,google/gemma-3-1b-it' || 'Qwen/Qwen3-0.6B' }}
75+
CRON_DEFAULT_MODELS: ${{ github.event_name == 'schedule' && 'mv3,mv2,ic4,ic3,resnet50,mobilebert,w2l,meta-llama/Llama-3.2-1B,meta-llama/Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8,meta-llama/Llama-3.2-1B-Instruct-QLORA_INT4_EO8,Qwen/Qwen3-0.6B,HuggingFaceTB/SmolLM2-135M,allenai/OLMo-1B-hf,google/gemma-3-1b-it' || 'Qwen/Qwen3-0.6B' }}
7676
CRON_DEFAULT_DEVICES: samsung_galaxy_s22+public
7777
run: |
7878
set -eux

.github/workflows/trunk.yml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,10 @@ jobs:
823823
--tsv_path ${TSV_PATH}
824824
echo "::endgroup::"
825825
826-
test-huggingface-transformers-coreml:
826+
test-huggingface-transformers-macos:
827827
# NB: Don't run this on fork PRs because they won't have access to the secret and would fail anyway
828828
if: ${{ !github.event.pull_request.head.repo.fork }}
829-
name: test-huggingface-transformers-coreml
829+
name: test-huggingface-transformers-macos
830830
uses: pytorch/test-infra/.github/workflows/macos_job.yml@main
831831
permissions:
832832
id-token: write
@@ -844,10 +844,10 @@ jobs:
844844
# phi4-mini|xnnpack|--quantize,
845845
# smollm2-135m|xnnpack|--quantize,
846846
# smollm3-3b|xnnpack|--quantize,
847+
# qwen3-1.7b|xnnpack|--quantize,
847848
# CoreML.
848849
llama3.2-1b|coreml_fp32_gpu|--quantize,
849850
qwen3-0.6b|coreml_fp32_gpu|--quantize,
850-
qwen3-1.7b|xnnpack|--quantize,
851851
smollm2-135m|coreml_fp32_gpu|--quantize,
852852
olmo-1b|coreml_fp32_gpu|--quantize,
853853
bert|coreml_fp32_gpu|--quantize,
@@ -979,3 +979,27 @@ jobs:
979979
# Run MCU models
980980
chmod +x examples/arm/run_mcu_models_fvp.sh
981981
examples/arm/run_mcu_models_fvp.sh --target=cortex-m55
982+
983+
test-models-windows:
984+
uses: pytorch/test-infra/.github/workflows/windows_job.yml@main
985+
strategy:
986+
fail-fast: false
987+
matrix:
988+
model: [linear, add, add_mul, ic3, ic4, mv2, mv3, resnet18, resnet50, vit, w2l, mobilebert, emformer_join, emformer_transcribe]
989+
backend: [portable, xnnpack-f32, xnnpack-q8]
990+
with:
991+
submodules: 'recursive'
992+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
993+
timeout: 60
994+
script: |
995+
conda init powershell
996+
997+
powershell -Command "& {
998+
Set-PSDebug -Trace 1
999+
\$ErrorActionPreference = 'Stop'
1000+
\$PSNativeCommandUseErrorActionPreference = \$true
1001+
1002+
.ci/scripts/setup-windows.ps1
1003+
1004+
powershell .ci/scripts/test_model.ps1 -modelName ${{ matrix.model }} -backend ${{ matrix.backend }}
1005+
}"

backends/apple/coreml/TARGETS

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,21 @@ runtime.python_library(
6161
)
6262

6363
runtime.python_library(
64-
name = "recipes",
65-
srcs = glob([
66-
"recipes/*.py",
67-
]),
64+
name = "coreml_recipes",
65+
srcs = [
66+
"recipes/__init__.py",
67+
"recipes/coreml_recipe_provider.py"
68+
],
6869
visibility = [
6970
"@EXECUTORCH_CLIENTS",
71+
"//executorch/export/...",
7072
],
7173
deps = [
7274
"fbsource//third-party/pypi/coremltools:coremltools",
75+
":coreml_recipe_types",
7376
":backend",
77+
":partitioner",
78+
":quantizer",
7479
"//caffe2:torch",
7580
"//executorch/exir:lib",
7681
"//executorch/exir/backend:compile_spec_schema",
@@ -80,6 +85,20 @@ runtime.python_library(
8085
],
8186
)
8287

88+
runtime.python_library(
89+
name = "coreml_recipe_types",
90+
srcs = [
91+
"recipes/coreml_recipe_types.py",
92+
],
93+
visibility = [
94+
"@EXECUTORCH_CLIENTS",
95+
"//executorch/export/...",
96+
],
97+
deps = [
98+
"//executorch/export:recipe",
99+
],
100+
)
101+
83102
runtime.cxx_python_extension(
84103
name = "executorchcoreml",
85104
srcs = [
@@ -124,7 +143,7 @@ runtime.python_test(
124143
"fbsource//third-party/pypi/pytest:pytest",
125144
":partitioner",
126145
":quantizer",
127-
":recipes",
146+
":coreml_recipes",
128147
"//caffe2:torch",
129148
"//pytorch/vision:torchvision",
130149
"fbsource//third-party/pypi/scikit-learn:scikit-learn",

backends/apple/coreml/compiler/torch_ops.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from coremltools.converters.mil.frontend.torch.ops import (
1616
_get_inputs,
1717
_get_kwinputs,
18+
noop,
1819
NUM_TO_NUMPY_DTYPE,
1920
NUM_TO_TORCH_DTYPE,
2021
split,
@@ -91,6 +92,28 @@ def _to_dim_order_copy(context, node):
9192
to(context, node)
9293

9394

95+
@register_torch_op(
96+
torch_alias=[
97+
"dim_order_ops::_clone_dim_order",
98+
"dim_order_ops._clone_dim_order",
99+
],
100+
override=False,
101+
)
102+
def _clone_dim_order(context, node):
103+
dim_order = _get_kwinputs(context, node, "dim_order", default=[None])[0]
104+
node.kwinputs.pop("dim_order")
105+
106+
# In CoreML, dim_order.val will be a ndarray, so we convert it to a list to check memory format.
107+
dim_order = [int(d) for d in dim_order.val]
108+
memory_format = get_memory_format(dim_order)
109+
assert (
110+
memory_format == _torch.contiguous_format
111+
), "Only contiguous memory format is supported in CoreML"
112+
113+
# Since CoreML only supports contiguous format, no dim_order preservation is needed. Treat this as a no-op clone.
114+
noop(context, node)
115+
116+
94117
# https://github.com/apple/coremltools/pull/2558
95118
@register_torch_op(
96119
torch_alias=["torchao::dequantize_affine", "torchao.dequantize_affine"],
@@ -175,11 +198,22 @@ def dequantize_codebook(context, node):
175198

176199
# Assert codebook is as expected. codebook.dim() = codes.dim() + 2
177200
assert len(codebook.shape) == 4, "Only rank 4 inputs are supported for codebook"
178-
assert codebook.shape[0] == 1, "Only grouped_channel granularity is supported"
179-
n_luts = codebook.shape[1]
180-
assert (
181-
codes.shape[1] % n_luts == 0
182-
), "codes.shape[1] must be divisible by codebook.shape[1]"
201+
assert (codebook.shape[0] == 1) or (
202+
codebook.shape[1] == 1
203+
), "Only grouped_channel granularity is supported"
204+
if codebook.shape[0] == 1:
205+
# LUT is per column group
206+
n_luts = codebook.shape[1]
207+
assert (
208+
codes.shape[1] % n_luts == 0
209+
), "codes.shape[1] must be divisible by codebook.shape[1]"
210+
else:
211+
# LUT is per row group
212+
n_luts = codebook.shape[0]
213+
assert (
214+
codes.shape[0] % n_luts == 0
215+
), "codes.shape[0] must be divisible by codebook.shape[0]"
216+
183217
assert codebook.shape[2] == 2**nbits
184218
assert codebook.shape[3] == 1, "Only scalar look up values are supported"
185219

0 commit comments

Comments
 (0)