Skip to content

Commit d7fd78b

Browse files
authored
[Windows] Run Python unit test CI on Windows (#13716)
Run unit test CI on Windows. I've disabled a few jobs (mainly pending tokenizers being available on Windows), but most everything is working out of box. I did also make a few additional fixes: * Shorten names for a few external project targets in CMake, in order to work around max path length limitations. * Update load code for kernel libraries in python. The binary names do not start with lib by default on Windows. This could be solved in the build, but it seems easier to just extend the glob. * Fix an issue blocking iterative builds for XNNPACK - we need to cause the schema move command to overwrite the existing artifact in the build directory. * Disable tokenizer install on Windows for now. Pending enablement in the tokenizers repo. * Fix paths in setup.py for Windows builds.
1 parent b2a8550 commit d7fd78b

File tree

16 files changed

+208
-26
lines changed

16 files changed

+208
-26
lines changed

.ci/scripts/unittest-windows.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
param (
2+
[string]$editable
3+
)
4+
5+
Set-PSDebug -Trace 1
6+
$ErrorActionPreference = 'Stop'
7+
$PSNativeCommandUseErrorActionPreference = $true
8+
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+
30+
# Run pytest with coverage
31+
# pytest -n auto --cov=./ --cov-report=xml
32+
pytest -v --full-trace -c pytest-windows.ini
33+
if ($LASTEXITCODE -ne 0) {
34+
Write-Host "Pytest invocation was unsuccessful. Exit code: $LASTEXITCODE."
35+
exit $LASTEXITCODE
36+
}

.github/workflows/_unittest.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ on:
1919
required: false
2020
type: string
2121
description: Install ExecuTorch in editable mode or not.
22+
default: 'false'
2223
python-version:
2324
required: false
2425
type: string
@@ -52,3 +53,14 @@ jobs:
5253
# This is needed to get the prebuilt PyTorch wheel from S3
5354
${CONDA_RUN} --no-capture-output pip install awscli==1.37.21
5455
.ci/scripts/unittest-macos.sh --build-tool "${{ inputs.build-tool }}" --build-mode "${{ inputs.build-mode }}" --editable "${{ inputs.editable }}"
56+
57+
windows:
58+
if: ${{ inputs.build-tool == 'cmake' }}
59+
uses: pytorch/test-infra/.github/workflows/windows_job.yml@main
60+
with:
61+
submodules: 'recursive'
62+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
63+
timeout: 120
64+
script: |
65+
conda init powershell
66+
powershell .ci/scripts/unittest-windows.ps1 -editable "${{ inputs.editable }}"

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,7 @@ xcuserdata/
6565

6666
# Android
6767
*.aar
68+
69+
# Windows
70+
*.dll
71+
*.pyd

backends/xnnpack/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ endforeach()
6262
if(WIN32 AND NOT CMAKE_CROSSCOMPILING)
6363
set(MV_COMMAND
6464
powershell -Command
65-
"Move-Item -Path ${_xnnpack_flatbuffer__outputs} -Destination ${_xnnpack_schema__outputs}"
65+
"Move-Item -Path ${_xnnpack_flatbuffer__outputs} -Destination ${_xnnpack_schema__outputs} -Force"
6666
)
6767
else()
6868
set(MV_COMMAND mv ${_xnnpack_flatbuffer__outputs} ${_xnnpack_schema__outputs})

conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import sys
2+
3+
collect_ignore_glob: list[str] = []
4+
5+
# Skip Apple tests on Windows. Note that some Core ML tests can run on Linux, as the AOT flow
6+
# is available. Tests will manage this internally. However, the coremltools import is not available
7+
# on Windows and causes collection to fail. The easiest way to manage this seems to be to just
8+
# skip collection for this subdirectory on unsupported platforms.
9+
if sys.platform == "win32":
10+
collect_ignore_glob += [
11+
"backends/apple/**",
12+
]

examples/apple/coreml/scripts/build_executor_runner.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ find "$CMAKE_BUILD_DIR_PATH/" -name 'libcoreml_inmemoryfs.a' -exec cp -f "{}" "$
9393
find "$CMAKE_BUILD_DIR_PATH/" -name 'libcoremldelegate.a' -exec cp -f "{}" "$LIBRARIES_DIR_PATH/libcoremldelegate.a" \;
9494
find "$CMAKE_BUILD_DIR_PATH/" -name 'libportable_ops_lib.a' -exec cp -f "{}" "$LIBRARIES_DIR_PATH/libportable_ops_lib.a" \;
9595
find "$CMAKE_BUILD_DIR_PATH/" -name 'libportable_kernels.a' -exec cp -f "{}" "$LIBRARIES_DIR_PATH/libportable_kernels.a" \;
96-
cp -f "$CMAKE_BUILD_DIR_PATH/third-party/flatcc_external_project/lib/libflatccrt.a" "$LIBRARIES_DIR_PATH/libflatccrt.a"
96+
cp -f "$CMAKE_BUILD_DIR_PATH/third-party/flatcc_ep/lib/libflatccrt.a" "$LIBRARIES_DIR_PATH/libflatccrt.a"
9797

9898
# Build the runner
9999
echo "ExecuTorch: Building runner"

examples/models/llama/source_transformation/custom_kv_cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def replace_kv_cache_with_quantized_kv_cache(module):
269269
executorch_package_path = executorch.__path__[-1]
270270
libs = list(
271271
glob.glob(
272-
f"{executorch_package_path}/**/libquantized_ops_aot_lib.*",
272+
f"{executorch_package_path}/**/*quantized_ops_aot_lib.*",
273273
recursive=True,
274274
)
275275
)

exir/tracer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from torch._decomp import get_decompositions
4949
from torch._dynamo.guards import Guard
5050
from torch._functorch.eager_transforms import _maybe_unwrap_functional_tensor
51+
5152
from torch.export import default_decompositions
5253
from torch.func import functionalize
5354
from torch.fx.operator_schemas import normalize_function

extension/llm/custom_ops/custom_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
package_path = Path(__file__).parent.resolve()
3434
logging.info(f"Looking for libcustom_ops_aot_lib.so in {package_path}")
3535

36-
libs = list(package_path.glob("**/libcustom_ops_aot_lib.*"))
36+
libs = list(package_path.glob("**/*custom_ops_aot_lib.*"))
3737

3838
assert len(libs) == 1, f"Expected 1 library but got {len(libs)}"
3939
logging.info(f"Loading custom ops library: {libs[0]}")

extension/llm/custom_ops/op_tile_crop_aot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
tile_crop = torch.ops.preprocess.tile_crop.default
1414
assert tile_crop is not None
1515
except:
16-
libs = list(Path(__file__).parent.resolve().glob("libcustom_ops_aot_lib.*"))
16+
libs = list(Path(__file__).parent.resolve().glob("*custom_ops_aot_lib.*"))
1717
assert len(libs) == 1, f"Expected 1 library but got {len(libs)}"
1818
logging.info(f"Loading custom ops library: {libs[0]}")
1919
torch.ops.load_library(libs[0])

0 commit comments

Comments
 (0)