-
Notifications
You must be signed in to change notification settings - Fork 369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NEST wheels #2170
Closed
Closed
NEST wheels #2170
Changes from all commits
Commits
Show all changes
77 commits
Select commit
Hold shift + click to select a range
f7422fe
Added wheel build environment to .gitignore
17a2643
Cache PYEXECDIR to allow Python to fish it out of CMake
ac9da28
Vendor deprecated distutils, useful for making distributions.
0983f78
Added script to prepare the wheel build environment
a25e1b9
Build wheel protocol to be executed by CI
fb5ee3e
Added CMake rig to `setup.py`. Only executed on wheel build.
6345f85
Actually use the rigged class
aed3c45
Fixed install location and RPATH of `pynestkernel.so` during buildwheel
a3e7352
Clone wheel env: current commit from current remote
Helveg 8256081
include sli in package
Helveg 294712a
set env var before py script
Helveg db7f135
make full clone
Helveg 966e7ab
Read NEST_CMAKE_BUILDWHEEL from env
Helveg 1aa2028
Install the Python source code to copy it. Auto detect all packages.
Helveg 5688e1f
CI attempt
Helveg 5495e5b
Set install prefix for tmp wheel env
Helveg 0c66356
copyright headers
Helveg cb5beb3
pip install wheel and cython
Helveg 7f35f5e
Install `libomp-dev`
Helveg 3fb809c
Fix MacOS OpenMP install command
Helveg cda72f8
didn't source'ing work?
Helveg ce90ab1
Install with `-j4`, set buildwheel env var in cibuildwheel options.
Helveg 88fd2eb
Hardcoded semver as a solution to obtain wheels
Helveg d283c70
Get Python libraries
Helveg 9ea1086
Guard commit SHA race conditions on GHA by using `actions/checkout`.
b65ee64
fixed uses/run combo
6b606ed
fixed prep_wheel_env changes
4c9b042
no sudo on GHA
a7c5800
use yum on manylinux_2010
2026e35
Added `cibuildwheel` wheels
Helveg ff5bf8f
Only 64 bit wheels(No OpenMP on 32 bit manylinux image compilers?)
Helveg ba1d368
Test `auto64` wheels
Helveg 99b7035
Add `cibuildwheel` config to pyproject. skip musllinux wheels
Helveg a3399ff
toml syntax error
Helveg 144cc13
fix `environment` key
Helveg 3ef78d8
place `wheelhouse` in default directory (parent of pwd at that point)
Helveg 18b1c0f
Use pypa `cibuildwheel` action. clean up. fixed copyright headers.
Helveg 86a5127
List `cmake` as a build system requirement.
Helveg b1cdf25
Added `build_sdist` and `upload_pypi` step
Helveg fffccce
Don't copy nest folder SLI files
Helveg e72a97e
pass "GHA" conditionally as arg when running on GHA
Helveg 5f55d66
added containerbuild script
Helveg 19c3a99
add SLI include inlining script
terhorstd b75be4a
move of inlining helper script to extras
terhorstd 9a5411e
fix updated func name
Helveg 0458534
turn on wheelbuild in containerbuild
Helveg 7e23dcf
Don't use cibuildwheel action. How to change working directory for it?
Helveg 1abe04a
Added cython to containerbuild build requirements
Helveg efa2e5e
check build with package dir arg
Helveg db96457
Merge branch 'circular-wheels' of https://github.com/Helveg/nest-simu…
jougs 75c7e76
added copyright statement
terhorstd f78d054
modify SLI imports from .cc files
terhorstd f9cd834
fix typo in filename
terhorstd d1c19e1
exclude versionchecker from the build wheel env
Helveg 258c5b4
Move PyNEST initializer code for SLI to standard NEST initializer
jougs f04b0f9
Merge branch 'circular-wheels' of https://github.com/Helveg/nest-simu…
jougs 13cea5a
fix multline raw strings
terhorstd 38f3237
Merge branch 'master' into circular-wheels
Helveg 7ee020c
Merge branch 'circular-wheels' of https://github.com/Helveg/nest-simu…
jougs c12ad63
Inline SLI init files to remove SLI library paths (#4)
terhorstd e702eb5
Move PyNEST initializer code for SLI to standard NEST initializer (#3)
jougs cbd7ffd
stop clang-format from asking to break the code
terhorstd 01013c0
change inline.py file handling
terhorstd 9c23c1c
Merge branch 'sli-init-inlining' into circular-wheels
Helveg c1c0af0
Merge branch 'circular-wheels' into sli-init-inlining
terhorstd 8dadbf1
Remove unused argument modulepath
jougs d594c97
Merge branch 'circular-wheels' of https://github.com/Helveg/nest-simu…
jougs cbed9fd
fix indent typo
terhorstd 9d74cbe
Merge branch 'sli-init-inlining' of github.com:terhorstd/nest-simulat…
terhorstd 326bb76
Merge branch 'sli-init-inlining' into circular-wheels
Helveg 5b1a007
Merge remote-tracking branch 'jougs/circular-wheels' into circular-wh…
Helveg a205b30
Inlined SLI code for wheel build
Helveg eee711f
Fix kwarg order for non kwarg calls
Helveg 3222d80
Skip unsupported <3.8 Python wheels
Helveg 4d17035
static code analysis fixes
Helveg 61b69ef
Hatcheting some `run` statements in examples and doc top prevent inline
Helveg f63c2e7
Merge branch 'master' into circular-wheels
Helveg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
name: Build wheels | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
build_wheels: | ||
name: Build wheels on ${{ matrix.os }} | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
os: [ubuntu-20.04, macOS-10.15] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
- name: Install OpenMP (MacOS) | ||
if: runner.os == 'macOS' | ||
run: brew install libomp | ||
- name: Install OpenMP (Ubuntu) | ||
if: runner.os == 'Linux' | ||
run: sudo apt-get install libomp-dev | ||
- name: Install Python wheel building prep requirements | ||
run: | | ||
python -m pip install wheel cython | ||
- name: Clone wheel building environment | ||
uses: actions/checkout@v2 | ||
with: | ||
path: build_wheel_env | ||
- name: Prepare wheel building environment | ||
run: | | ||
source extras/wheelbuild/wheelbuild.sh GHA | ||
- name: Build wheels | ||
uses: pypa/[email protected] | ||
with: | ||
package-dir: build_wheel_env | ||
- uses: actions/upload-artifact@v2 | ||
with: | ||
path: ./wheelhouse/*.whl | ||
|
||
build_sdist: | ||
name: Build source distribution | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
- name: Build sdist | ||
run: python setup.py sdist | ||
- uses: actions/upload-artifact@v2 | ||
with: | ||
path: dist/*.tar.gz | ||
|
||
upload_pypi: | ||
needs: [build_wheels, build_sdist] | ||
runs-on: ubuntu-latest | ||
# upload to PyPI on every tag starting with 'v' | ||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') | ||
# alternatively, to publish when a GitHub Release is created, use the following rule: | ||
# if: github.event_name == 'release' && github.event.action == 'published' | ||
steps: | ||
- uses: actions/download-artifact@v2 | ||
with: | ||
name: artifact | ||
path: dist | ||
|
||
- uses: pypa/[email protected] | ||
with: | ||
user: __token__ | ||
password: ${{ secrets.pypi_password }} | ||
# To test: repository_url: https://test.pypi.org/legacy/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
|
||
__pycache__/ | ||
build/ | ||
build_wheel_env/ | ||
_build/ | ||
install/ | ||
reports/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# | ||
# inline_sli.py | ||
# | ||
# This file is part of NEST. | ||
# | ||
# Copyright (C) 2004 The NEST Initiative | ||
# | ||
# NEST is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# NEST is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with NEST. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import re | ||
import sys | ||
from pathlib import Path | ||
|
||
SLI_LIBPATH = Path(__file__).parent.parent / "lib" / "sli" | ||
|
||
|
||
def replaced(filename, noinclude=None): | ||
''' | ||
Recursively replace "(xy) run" SLI commands. | ||
''' | ||
if noinclude is None: | ||
noinclude = [] | ||
sliimport = re.compile(r'\((?P<name>[^)]+)\) run') | ||
for no, line in enumerate(filename.open('r', encoding="utf8")): | ||
found = False | ||
for match in sliimport.finditer(line): | ||
incfile = (SLI_LIBPATH / match.group('name')).with_suffix(".sli") | ||
if incfile in noinclude: | ||
continue | ||
if not incfile.is_file(): | ||
yield(f"%%% INSERT FAILED FOR >>> {incfile} <<<\n") | ||
yield(f"%%% {line}") | ||
continue | ||
yield(f"%%% INSERT {incfile} LITERALLY\n") | ||
yield(f"%%% L{no}: {line}") | ||
noinclude.append(incfile) | ||
for includedline in replaced(incfile, noinclude): | ||
yield includedline.replace('"', "'") | ||
yield(f"%%% END {incfile}\n") | ||
found = True | ||
if not found: | ||
yield f"{line}" | ||
|
||
|
||
def inline(files): | ||
''' | ||
SLI code inlining. | ||
''' | ||
for arg in files: | ||
filename = Path(arg) | ||
newfile = filename.with_suffix(".new") | ||
with newfile.open("w", encoding="utf8") as outfile: | ||
for line in replaced(filename): | ||
outfile.write(line) | ||
newfile.rename(filename) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# _vendored.py | ||
# | ||
# This file is part of NEST. | ||
# | ||
# Copyright (C) 2004 The NEST Initiative | ||
# | ||
# NEST is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# NEST is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with NEST. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
# This code is taken from the Python `distutils` module. | ||
|
||
import os | ||
|
||
_path_created = dict() | ||
|
||
def mkpath(name, mode=0o777, verbose=1, dry_run=0): | ||
"""Create a directory and any missing ancestor directories. | ||
|
||
If the directory already exists (or if 'name' is the empty string, which | ||
means the current directory, which of course exists), then do nothing. | ||
Raise DistutilsFileError if unable to create some directory along the way | ||
(eg. some sub-path exists, but is a file rather than a directory). | ||
If 'verbose' is true, print a one-line summary of each mkdir to stdout. | ||
Return the list of directories actually created. | ||
""" | ||
|
||
global _path_created | ||
|
||
# Detect a common bug -- name is None | ||
if not isinstance(name, str): | ||
raise Exception( | ||
"mkpath: 'name' must be a string (got %r)" % (name,)) | ||
|
||
# XXX what's the better way to handle verbosity? print as we create | ||
# each directory in the path (the current behaviour), or only announce | ||
# the creation of the whole path? (quite easy to do the latter since | ||
# we're not using a recursive algorithm) | ||
|
||
name = os.path.normpath(name) | ||
created_dirs = [] | ||
if os.path.isdir(name) or name == '': | ||
return created_dirs | ||
if _path_created.get(os.path.abspath(name)): | ||
return created_dirs | ||
|
||
(head, tail) = os.path.split(name) | ||
tails = [tail] # stack of lone dirs to create | ||
|
||
while head and tail and not os.path.isdir(head): | ||
(head, tail) = os.path.split(head) | ||
tails.insert(0, tail) # push next higher dir onto stack | ||
|
||
# now 'head' contains the deepest directory that already exists | ||
# (that is, the child of 'head' in 'name' is the highest directory | ||
# that does *not* exist) | ||
for d in tails: | ||
#print "head = %s, d = %s: " % (head, d), | ||
head = os.path.join(head, d) | ||
abs_head = os.path.abspath(head) | ||
|
||
if _path_created.get(abs_head): | ||
continue | ||
|
||
if not dry_run: | ||
try: | ||
os.mkdir(head, mode) | ||
except OSError as exc: | ||
if not (exc.errno == errno.EEXIST and os.path.isdir(head)): | ||
raise Exception( | ||
"could not create '%s': %s" % (head, exc.args[-1])) | ||
created_dirs.append(head) | ||
|
||
_path_created[abs_head] = 1 | ||
return created_dirs | ||
|
||
def copy_py_tree(src, dst, preserve_mode=1, preserve_times=1, | ||
preserve_symlinks=0, update=0, verbose=1, dry_run=0, exclude=None): | ||
"""Copy an entire directory tree 'src' to a new location 'dst'. | ||
|
||
Both 'src' and 'dst' must be directory names. If 'src' is not a | ||
directory, raise DistutilsFileError. If 'dst' does not exist, it is | ||
created with 'mkpath()'. The end result of the copy is that every | ||
file in 'src' is copied to 'dst', and directories under 'src' are | ||
recursively copied to 'dst'. Return the list of files that were | ||
copied or might have been copied, using their output name. The | ||
return value is unaffected by 'update' or 'dry_run': it is simply | ||
the list of all files under 'src', with the names changed to be | ||
under 'dst'. | ||
|
||
'preserve_mode' and 'preserve_times' are the same as for | ||
'copy_file'; note that they only apply to regular files, not to | ||
directories. If 'preserve_symlinks' is true, symlinks will be | ||
copied as symlinks (on platforms that support them!); otherwise | ||
(the default), the destination of the symlink will be copied. | ||
'update' and 'verbose' are the same as for 'copy_file'. | ||
""" | ||
from distutils.file_util import copy_file | ||
|
||
if exclude is None: | ||
exclude = [] | ||
|
||
if not dry_run and not os.path.isdir(src): | ||
raise Exception( | ||
"cannot copy tree '%s': not a directory" % src) | ||
try: | ||
names = os.listdir(src) | ||
except OSError as e: | ||
if dry_run: | ||
names = [] | ||
else: | ||
raise Exception( | ||
"error listing files in '%s': %s" % (src, e.strerror)) | ||
|
||
if not dry_run: | ||
mkpath(dst, verbose=verbose) | ||
|
||
outputs = [] | ||
|
||
for n in names: | ||
src_name = os.path.join(src, n) | ||
dst_name = os.path.join(dst, n) | ||
|
||
if n.startswith('.nfs'): | ||
# skip NFS rename files | ||
continue | ||
|
||
if preserve_symlinks and os.path.islink(src_name): | ||
link_dest = os.readlink(src_name) | ||
if verbose >= 1: | ||
log.info("linking %s -> %s", dst_name, link_dest) | ||
if not dry_run: | ||
os.symlink(link_dest, dst_name) | ||
outputs.append(dst_name) | ||
|
||
elif os.path.isdir(src_name): | ||
outputs.extend( | ||
copy_py_tree(src_name, dst_name, preserve_mode, | ||
preserve_times, preserve_symlinks, update, | ||
verbose=verbose, dry_run=dry_run)) | ||
elif n.endswith(".py") and n not in exclude: | ||
copy_file(src_name, dst_name, preserve_mode, | ||
preserve_times, update, verbose=verbose, | ||
dry_run=dry_run) | ||
outputs.append(dst_name) | ||
|
||
return outputs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
set -e -u -x | ||
|
||
rm -rf /opt/python/cp35-cp35m | ||
export NEST_CMAKE_BUILDWHEEL=ON | ||
|
||
for PYBIN in /opt/python/*/bin; do | ||
"${PYBIN}/pip" install wheel cmake cython | ||
export PATH="${PYBIN}":$PATH | ||
which cmake | ||
"${PYBIN}/python" ./setup.py bdist_wheel | ||
done | ||
|
||
# Bundle external shared libraries into the wheels | ||
/opt/python/cp39-cp39/bin/pip install auditwheel | ||
for whl in ./dist/*.whl; do | ||
/opt/python/cp39-cp39/bin/auditwheel repair "$whl" | ||
done |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should insert comment why: