Build and test python package on Windows CI (#3049)

This commit is contained in:
Cheng
2026-01-24 07:22:36 +09:00
committed by GitHub
parent dc81c1503a
commit fd27829efa
10 changed files with 44 additions and 12 deletions
+10 -2
View File
@@ -3,7 +3,8 @@ name: 'Build on Windows'
runs:
using: 'composite'
steps:
- name: Build CPP only
- name: Install Python package
id: python-build
shell: cmd
env:
# For MSVC, Ninja/Release is the only config supported by ccache.
@@ -14,5 +15,12 @@ runs:
-DCMAKE_CXX_COMPILER=cl
-DCMAKE_RC_COMPILER=rc
run: |
cmake . -B build %CMAKE_ARGS%
uv pip install ".[dev]" -v
:: Pass the CMAKE_ARGS to following steps.
>>%GITHUB_OUTPUT% ECHO CMAKE_ARGS=%CMAKE_ARGS%
- name: Build CPP only
shell: cmd
run: |
cmake . -B build ${{ steps.python-build.outputs.CMAKE_ARGS }}
cmake --build build -j %NUMBER_OF_PROCESSORS%
+9 -4
View File
@@ -20,10 +20,6 @@ runs:
key: ccache-${{ runner.os }}-${{ runner.arch }}-cpu
max-size: 1GB
- uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version }}
- name: Setup Visual Studio cmd
shell: cmd
run: |
@@ -35,3 +31,12 @@ runs:
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64
:: Export to all steps.
>>%GITHUB_ENV% set
- uses: astral-sh/setup-uv@v7
- name: Setup Python venv
shell: cmd
run: |
uv venv --python ${{ inputs.python-version }}
call ".venv/Scripts/activate.bat"
>>%GITHUB_ENV% set
+7
View File
@@ -3,6 +3,13 @@ name: 'Run tests on Windows'
runs:
using: 'composite'
steps:
- name: Run Python tests - CPU
shell: bash
run: |
echo "::group::Python tests - CPU"
python -m unittest discover python/tests -v
echo "::endgroup::"
- name: Run CPP tests - CPU
shell: bash
env:
-2
View File
@@ -83,8 +83,6 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-windows
with:
use-ccache: false
- uses: ./.github/actions/build-windows
- uses: ./.github/actions/test-windows
+1 -1
View File
@@ -471,7 +471,7 @@ mx::array create_array(ArrayInitType v, std::optional<mx::Dtype> t) {
if (auto pv = std::get_if<nb::bool_>(&v); pv) {
return mx::array(nb::cast<bool>(*pv), t.value_or(mx::bool_));
} else if (auto pv = std::get_if<nb::int_>(&v); pv) {
auto val = nb::cast<long>(*pv);
auto val = nb::cast<int64_t>(*pv);
auto default_type = (val > std::numeric_limits<int>::max() ||
val < std::numeric_limits<int>::min())
? mx::int64
+1 -1
View File
@@ -11,7 +11,7 @@ mx::array to_array(
if (auto pv = std::get_if<nb::bool_>(&v); pv) {
return mx::array(nb::cast<bool>(*pv), dtype.value_or(mx::bool_));
} else if (auto pv = std::get_if<nb::int_>(&v); pv) {
auto val = nb::cast<long>(*pv);
auto val = nb::cast<int64_t>(*pv);
auto default_type = (val > std::numeric_limits<int>::max() ||
val < std::numeric_limits<int>::min())
? mx::int64
+5
View File
@@ -1618,6 +1618,11 @@ class TestArray(mlx_tests.MLXTestCase):
self.assertEqual(mv_mx.format, "Q", f"{mlx_dtype}{np_dtype}")
elif np_dtype == np.int64:
self.assertEqual(mv_mx.format, "q", f"{mlx_dtype}{np_dtype}")
# for windows long is 32bit and numpy returns L/l.
elif np_dtype == np.uint32 and platform.system() == "Windows":
self.assertEqual(mv_mx.format, "I", f"{mlx_dtype}{np_dtype}")
elif np_dtype == np.int32 and platform.system() == "Windows":
self.assertEqual(mv_mx.format, "i", f"{mlx_dtype}{np_dtype}")
else:
self.assertEqual(
mv_mx.format, mv_np.format, f"{mlx_dtype}{np_dtype}"
+8
View File
@@ -1,6 +1,7 @@
# Copyright © 2023 Apple Inc.
import os
import platform
import tempfile
import unittest
from pathlib import Path
@@ -126,6 +127,7 @@ class TestLoad(mlx_tests.MLXTestCase):
mx.array_equal(load_dict["test"], save_dict["test"])
)
@unittest.skipIf(platform.system() == "Windows", "GGUF is disabled on Windows")
def test_save_and_load_gguf(self):
if not os.path.isdir(self.test_dir):
os.mkdir(self.test_dir)
@@ -186,6 +188,7 @@ class TestLoad(mlx_tests.MLXTestCase):
out = mx.load(f)["tensor"]
self.assertTrue(mx.allclose(mx.from_fp8(out), expected))
@unittest.skipIf(platform.system() == "Windows", "GGUF is disabled on Windows")
def test_save_and_load_gguf_metadata_basic(self):
if not os.path.isdir(self.test_dir):
os.mkdir(self.test_dir)
@@ -218,6 +221,7 @@ class TestLoad(mlx_tests.MLXTestCase):
self.assertTrue("meta" in meta_load_dict)
self.assertEqual(meta_load_dict["meta"], "data")
@unittest.skipIf(platform.system() == "Windows", "GGUF is disabled on Windows")
def test_save_and_load_gguf_metadata_arrays(self):
if not os.path.isdir(self.test_dir):
os.mkdir(self.test_dir)
@@ -253,6 +257,7 @@ class TestLoad(mlx_tests.MLXTestCase):
metadata = {"meta": arr}
mx.save_gguf(save_file_mlx, save_dict, metadata)
@unittest.skipIf(platform.system() == "Windows", "GGUF is disabled on Windows")
def test_save_and_load_gguf_metadata_mixed(self):
if not os.path.isdir(self.test_dir):
os.mkdir(self.test_dir)
@@ -396,6 +401,9 @@ class TestLoad(mlx_tests.MLXTestCase):
aload = mx.load(save_file)["a"]
self.assertTrue(mx.array_equal(a, aload))
if platform.system() == "Windows":
return
save_file = os.path.join(self.test_dir, "a.gguf")
mx.save_gguf(save_file, {"a": a})
aload = mx.load(save_file)["a"]
+2 -2
View File
@@ -18,8 +18,8 @@ class TestMemory(mlx_tests.MLXTestCase):
self.assertEqual(mx.set_cache_limit(old_limit), old_limit)
old_limit = mx.set_memory_limit(10)
self.assertTrue(mx.set_memory_limit(old_limit), 10)
self.assertTrue(mx.set_memory_limit(old_limit), old_limit)
self.assertEqual(mx.set_memory_limit(old_limit), 10)
self.assertEqual(mx.set_memory_limit(old_limit), old_limit)
# Query active and peak memory
a = mx.zeros((4096,))
+1
View File
@@ -229,6 +229,7 @@ if __name__ == "__main__":
"dev": [
"numpy>=2",
"pre-commit",
"psutil",
"torch>=2.9",
"typing_extensions",
],