Skip to content

Commit f5f20df

Browse files
CI: Re-enable Emscripten/Pyodide CI job for NumPy
This commit performs the following actions: 1. Adds WASM builds to the CPU family for Meson configurations, but without SSE or SIMD instructions. 2. Removes CPU feature detection message for an unsupported architecture. 3. Enables `IEEE_QUAD_LE` longdouble format for the wasm32 target (cross-builds). 4. Enables run for Emscripten/Pyodide wheels by setting the `if:` condition to `true`. 5. Uses recursive submodules to ensure that vendored-meson is received. 6. Moves the Meson cross file to `tools/ci/emscripten/` (i.e., creates a separate Emscripten folder to store relevant files) 7. Adds a patch for vendored-meson detection for Pyodide and applies this Pyodide-meson patch in the Emscripten CI jobs 8. Builds wasm32 wheels without BLAS and LAPACK support (see numpy#24750 (comment)) 9. Forces coloured and prettified outputs for test runs Some of these changes have been copied with updates and suggestions received from numpy#24603 on 23/02/2024 and authorship is preserved with this commit. [skip cirrus] [skip circle] [skip azp] Co-Authored-By: Ralf Gommers <[email protected]>
1 parent e1e0e84 commit f5f20df

File tree

5 files changed

+119
-34
lines changed

5 files changed

+119
-34
lines changed

.github/workflows/emscripten.yml

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# To enable this workflow on a fork, comment out:
2-
#
3-
# if: github.repository == 'numpy/numpy'
41
name: Test Emscripten/Pyodide build
52

63
on:
@@ -9,6 +6,9 @@ on:
96
- main
107
- maintenance/**
118

9+
env:
10+
FORCE_COLOR: 3
11+
1212
concurrency:
1313
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
1414
cancel-in-progress: true
@@ -20,50 +20,65 @@ jobs:
2020
build-wasm-emscripten:
2121
name: Build NumPy distribution for Pyodide
2222
runs-on: ubuntu-22.04
23-
if: false # NOTE: job disabled, it needs to be moved to Meson (see gh-24603)
24-
# if: "github.repository == 'numpy/numpy'"
23+
# To enable this workflow on a fork, comment out:
24+
if: github.repository == 'numpy/numpy'
2525
env:
26-
PYODIDE_VERSION: 0.23.1
26+
PYODIDE_VERSION: 0.25.0
2727
# PYTHON_VERSION and EMSCRIPTEN_VERSION are determined by PYODIDE_VERSION.
2828
# The appropriate versions can be found in the Pyodide repodata.json
2929
# "info" field, or in Makefile.envs:
3030
# https://github.com/pyodide/pyodide/blob/main/Makefile.envs#L2
31-
PYTHON_VERSION: 3.11.2
32-
EMSCRIPTEN_VERSION: 3.1.32
31+
PYTHON_VERSION: 3.11.3
32+
EMSCRIPTEN_VERSION: 3.1.46
3333
NODE_VERSION: 18
3434
steps:
35-
- name: Checkout numpy
35+
- name: Checkout NumPy
3636
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
3737
with:
38-
submodules: true
39-
# versioneer.py requires the latest tag to be reachable. Here we
40-
# fetch the complete history to get access to the tags.
41-
# A shallow clone can work when the following issue is resolved:
42-
# https://github.com/actions/checkout/issues/338
43-
fetch-depth: 0
44-
45-
- name: set up python
38+
submodules: recursive
39+
# The fetch-tags input shall fetch tags for versioneer.py
40+
# without the need to fetch the entire history, see
41+
# https://github.com/actions/checkout#usage
42+
fetch-tags: true
43+
44+
- name: Set up Python ${{ env.PYTHON_VERSION }}
4645
id: setup-python
4746
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
4847
with:
4948
python-version: ${{ env.PYTHON_VERSION }}
5049

51-
- uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021 # v14
50+
- name: Set up Emscripten toolchain
51+
uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021 # v14
5252
with:
5353
version: ${{ env.EMSCRIPTEN_VERSION }}
5454
actions-cache-folder: emsdk-cache
5555

5656
- name: Install pyodide-build
57-
run: pip install "pydantic<2" pyodide-build==$PYODIDE_VERSION
57+
run: pip install "pydantic<2" pyodide-build==${{ env.PYODIDE_VERSION }}
58+
59+
- name: Find installation for pyodide-build
60+
shell: python
61+
run: |
62+
import os
63+
import pyodide_build
64+
65+
pyodide_build_path = pyodide_build.__file__[:-12]
66+
67+
env_file = os.getenv('GITHUB_ENV')
68+
69+
with open(env_file, "a") as myfile:
70+
myfile.write(f"PYODIDE_BUILD_PATH={pyodide_build_path}\n")
71+
72+
- name: Apply patch(es) for pyodide-build installation
73+
run: |
74+
ls -a ${{ env.PYODIDE_BUILD_PATH }}
75+
patch -d "${{ env.PYODIDE_BUILD_PATH }}" -p1 < tools/ci/emscripten/0001-do-not-set-meson-environment-variable-pyodide-gh-4502.patch
5876
59-
- name: Build
77+
- name: Build NumPy for Pyodide
6078
run: |
61-
# Pyodide is still in the process of adding better/easier support for
62-
# non-setup.py based builds.
63-
cp pyproject.toml.setuppy pyproject.toml
64-
CFLAGS=-g2 LDFLAGS=-g2 pyodide build
79+
pyodide build -Cbuild-dir=build -Csetup-args="--cross-file=$PWD/tools/ci/emscripten/emscripten.meson.cross" -Csetup-args="-Dblas=none" -Csetup-args="-Dlapack=none"
6580
66-
- name: set up node
81+
- name: Set up Node.js
6782
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
6883
with:
6984
node-version: ${{ env.NODE_VERSION }}
@@ -73,11 +88,10 @@ jobs:
7388
pyodide venv .venv-pyodide
7489
source .venv-pyodide/bin/activate
7590
pip install dist/*.whl
76-
python -c "import sys; print(sys.platform)"
7791
pip install -r requirements/emscripten_test_requirements.txt
7892
7993
- name: Test NumPy for Pyodide
8094
run: |
8195
source .venv-pyodide/bin/activate
8296
cd ..
83-
python numpy/runtests.py -n -vv
97+
pytest --pyargs numpy -m "not slow"

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ pip-wheel-metadata
9797
*.patch
9898
*.diff
9999

100+
# Do not ignore the following patches: #
101+
########################################
102+
!tools/ci/emscripten/0001-do-not-set-meson-environment-variable-pyodide-gh-4502.patch
103+
100104
# OS generated files #
101105
######################
102106
.DS_Store*

meson_cpu/meson.build

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,30 +92,27 @@ min_features = {
9292
'ppc64': [],
9393
's390x': [],
9494
'arm': [],
95-
'aarch64': [ASIMD]
95+
'aarch64': [ASIMD],
96+
'wasm32': [],
9697
}.get(cpu_family, [])
9798
if host_machine.endian() == 'little' and cpu_family == 'ppc64'
9899
min_features = [VSX2]
99100
endif
100101

101-
# Used by build option 'max/native/detect'
102+
# Used by build option 'max'
102103
max_features_dict = {
103104
'x86': X86_FEATURES,
104105
'x86_64': X86_FEATURES,
105106
'ppc64': PPC64_FEATURES,
106107
's390x': S390X_FEATURES,
107108
'arm': ARM_FEATURES,
108109
'aarch64': ARM_FEATURES,
110+
'wasm32': {},
109111
}.get(cpu_family, {})
110112
max_features = []
111113
foreach fet_name, fet_obj : max_features_dict
112114
max_features += [fet_obj]
113115
endforeach
114-
if max_features.length() == 0
115-
message('Disabling CPU feature detection due to unsupported architecture: "' + cpu_family + '"')
116-
CPU_CONF_BASELINE = 'none'
117-
CPU_CONF_DISPATCH = 'none'
118-
endif
119116

120117
parse_options = {
121118
'cpu-baseline': CPU_CONF_BASELINE,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
From e08ebf0e90f632547c8ff5b396ec0c4ddd65aad4 Mon Sep 17 00:00:00 2001
2+
From: Gyeongjae Choi <[email protected]>
3+
Date: Sat, 10 Feb 2024 03:28:01 +0900
4+
Subject: [PATCH] Update numpy to 1.26.4 and don't set MESON env variable
5+
(#4502)
6+
7+
From meson-python 0.15, $MESON env variable is used to overwrite the meson binary
8+
path. We don't want that behavior.
9+
---
10+
pypabuild.py | 22 +++++++++++++++-------
11+
1 file changed, 15 insertions(+), 7 deletions(-)
12+
13+
diff --git a/pypabuild.py b/pypabuild.py
14+
index 9d0107a8..6961b14e 100644
15+
--- a/pypabuild.py
16+
+++ b/pypabuild.py
17+
@@ -40,6 +40,19 @@ AVOIDED_REQUIREMENTS = [
18+
"patchelf",
19+
]
20+
21+
+# corresponding env variables for symlinks
22+
+SYMLINK_ENV_VARS = {
23+
+ "cc": "CC",
24+
+ "c++": "CXX",
25+
+ "ld": "LD",
26+
+ "lld": "LLD",
27+
+ "ar": "AR",
28+
+ "gcc": "GCC",
29+
+ "ranlib": "RANLIB",
30+
+ "strip": "STRIP",
31+
+ "gfortran": "FC", # https://mesonbuild.com/Reference-tables.html#compiler-and-linker-selection-variables
32+
+}
33+
+
34+
35+
def _gen_runner(
36+
cross_build_env: Mapping[str, str],
37+
@@ -207,13 +220,8 @@ def make_command_wrapper_symlinks(symlink_dir: Path) -> dict[str, str]:
38+
symlink_path.unlink()
39+
40+
symlink_path.symlink_to(pywasmcross_exe)
41+
- if symlink == "c++":
42+
- var = "CXX"
43+
- elif symlink == "gfortran":
44+
- var = "FC" # https://mesonbuild.com/Reference-tables.html#compiler-and-linker-selection-variables
45+
- else:
46+
- var = symlink.upper()
47+
- env[var] = str(symlink_path)
48+
+ if symlink in SYMLINK_ENV_VARS:
49+
+ env[SYMLINK_ENV_VARS[symlink]] = str(symlink_path)
50+
51+
return env
52+
53+
--
54+
2.39.3 (Apple Git-145)
55+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# compiler paths are omitted intentionally so we can override the compiler using environment variables
2+
[binaries]
3+
exe_wrapper = 'node'
4+
pkgconfig = 'pkg-config'
5+
6+
[properties]
7+
needs_exe_wrapper = true
8+
skip_sanity_check = true
9+
longdouble_format = 'IEEE_QUAD_LE' # for numpy
10+
11+
[host_machine]
12+
system = 'emscripten'
13+
cpu_family = 'wasm32'
14+
cpu = 'wasm'
15+
endian = 'little'

0 commit comments

Comments
 (0)