Skip to content

Commit

Permalink
Merge 2ea0251 into df81221
Browse files Browse the repository at this point in the history
  • Loading branch information
mstimberg committed Feb 15, 2021
2 parents df81221 + 2ea0251 commit c3682a0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 21 deletions.
55 changes: 38 additions & 17 deletions .github/workflows/publish_to_pypi.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
name: Publish source package to TestPyPI
on: [push]
name: Build and publish to TestPyPI or PyPI
on: [push, pull_request]

jobs:
build-n-publish:
name: Build and publish source package to TestPyPI and PyPI
runs-on: ubuntu-latest
name: Build wheels on ${{ matrix.os }} and publish to (Test)PyPI
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-20.04, windows-2019, macOS-10.15 ]
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -13,20 +16,38 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
- name: Build source tarball (only on Linux)
run: |
python -m pip install --upgrade pip
pip install setuptools cython
- name: Build source tarball
run: python setup.py sdist --formats=gztar --with-cython --fail-on-error
- name: Publish distribution 📦 to Test PyPI
if: ${{ ! startsWith(github.ref, 'refs/tags') }}
uses: pypa/gh-action-pypi-publish@master
python -m pip install "cython>=0.29" numpy>=1.15 setuptools
python setup.py sdist --formats=gztar --with-cython --fail-on-error
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
- name: Build wheels
uses: joerick/cibuildwheel@v1.9.0
with:
password: ${{ secrets.test_pypi_password }}
repository_url: https://test.pypi.org/legacy/
output-dir: dist
env:
CIBW_BEFORE_BUILD: pip install --only-binary numpy "cython>=0.29" numpy>=1.15 setuptools
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.7"
CIBW_ARCHS: auto64
CIBW_ARCHS_MACOS: x86_64 universal2
CIBW_TEST_SKIP: '*_arm64 *_universal2:arm64'
CIBW_SKIP: pp*
CIBW_TEST_COMMAND: python {project}/dev/continuous-integration/run_simple_test.py
CIBW_TEST_REQUIRES: pytest
- name: Publish distribution 📦 to Test PyPI
if: github.ref == 'refs/heads/master'
run: |
pip install twine
twine upload -r testpypi dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.test_pypi_password }}
- name: Publish distribution release 📦 to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.pypi_password }}
if: ${{ startsWith(github.ref, 'refs/tags') }}
run: |
pip install twine
twine upload dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.pypi_password }}
50 changes: 47 additions & 3 deletions brian2/codegen/cpp_prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import tempfile

from brian2.core.preferences import prefs, BrianPreference
from brian2.utils.logger import get_logger
from brian2.utils.logger import get_logger, std_silent

__all__ = ['get_compiler_and_args', 'get_msvc_env', 'compiler_supports_c99',
'C99Check']
Expand Down Expand Up @@ -188,6 +188,38 @@
'''),
)

# check whether compiler supports a flag
# Adapted from https://github.com/pybind/pybind11/
def _determine_flag_compatibility(compiler, flagname):
import tempfile
from distutils.errors import CompileError
with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f, std_silent():
f.write('int main (int argc, char **argv) { return 0; }')
try:
compiler.compile([f.name], extra_postargs=[flagname])
except CompileError:
logger.warn(f'Removing unsupported flag \'{flagname}\' from '
f'compiler flags.')
return False
return True

_compiler_flag_compatibility = {}
def has_flag(compiler, flagname):
if compiler.compiler_type == 'msvc':
# MSVC does not raise an error for illegal flags, so determining
# whether it accepts a flag would mean parsing the output for warnings
# This is non-trivial so we don't do it (the main reason to check
# flags in the first place are differences between gcc and clang)
return True
else:
compiler_exe = ' '.join(compiler.executables['compiler_cxx'])

if (compiler_exe, flagname) not in _compiler_flag_compatibility:
compatibility = _determine_flag_compatibility(compiler, flagname)
_compiler_flag_compatibility[(compiler_exe, flagname)] = compatibility

return _compiler_flag_compatibility[(compiler_exe, flagname)]


def get_compiler_and_args():
'''
Expand All @@ -200,8 +232,20 @@ def get_compiler_and_args():
if extra_compile_args is None:
if compiler in ('gcc', 'unix'):
extra_compile_args = prefs['codegen.cpp.extra_compile_args_gcc']
if compiler == 'msvc':
elif compiler == 'msvc':
extra_compile_args = prefs['codegen.cpp.extra_compile_args_msvc']
else:
extra_compile_args = []
logger.warn(f'Unsupported compiler \'{compiler}\'.')

from distutils.ccompiler import new_compiler
from distutils.sysconfig import customize_compiler
compiler_obj = new_compiler(compiler=compiler, verbose=0)
customize_compiler(compiler_obj)
extra_compile_args = [flag
for flag in extra_compile_args
if has_flag(compiler_obj, flag)]

return compiler, extra_compile_args


Expand All @@ -222,7 +266,7 @@ def get_msvc_env():
arch_name=arch_name)
return None, vcvars_cmd

# Search for MSVC environemtn if not already cached
# Search for MSVC environment if not already cached
if _msvc_env is None:
try:
_msvc_env = msvc.msvc14_get_vc_env(arch_name)
Expand Down
29 changes: 28 additions & 1 deletion brian2/tests/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest

from brian2 import prefs, clear_cache, _cache_dirs_and_extensions
from brian2.codegen.cpp_prefs import compiler_supports_c99
from brian2.codegen.cpp_prefs import compiler_supports_c99, get_compiler_and_args
from brian2.codegen.optimisation import optimise_statements
from brian2.codegen.translation import (analyse_identifiers,
get_identifiers_recursively,
Expand All @@ -21,6 +21,7 @@
from brian2.devices.device import auto_target, device
from brian2.units.fundamentalunits import Unit
from brian2.units import second, ms
from brian2.utils.logger import catch_logs

FakeGroup = namedtuple('FakeGroup', ['variables'])

Expand Down Expand Up @@ -452,6 +453,32 @@ def test_compiler_c99():
assert c99_support


def test_cpp_flags_support():
from distutils.ccompiler import get_default_compiler
compiler = get_default_compiler()
old_prefs = prefs['codegen.cpp.extra_compile_args']

# Should always be supported
if compiler in ('gcc', 'unix'):
prefs['codegen.cpp.extra_compile_args'] = ['-w']
else:
prefs['codegen.cpp.extra_compile_args'] = ['/w']
_, compile_args = get_compiler_and_args()
assert compile_args == prefs['codegen.cpp.extra_compile_args']

# Should never be supported and raise a warning
if compiler in ('gcc', 'unix'):
prefs['codegen.cpp.extra_compile_args'] = ['-invalidxyz']
else:
prefs['codegen.cpp.extra_compile_args'] = ['/invalidxyz']
with catch_logs() as l:
_, compile_args = get_compiler_and_args()
assert len(l) == 1 and l[0][0] == 'WARNING'
assert compile_args == []

prefs['codegen.cpp.extra_compile_args'] = old_prefs


if __name__ == '__main__':
test_auto_target()
test_analyse_identifiers()
Expand Down
8 changes: 8 additions & 0 deletions dev/continuous-integration/run_simple_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Run a simple test that uses the main simulation elements and force code
# generation to use Cython
from brian2 import prefs
from brian2.tests.test_synapses import test_transmission_simple

prefs.codegen.target = 'cython'

test_transmission_simple()

0 comments on commit c3682a0

Please sign in to comment.