Commit 99309aed authored by Stefan Behnel's avatar Stefan Behnel

Add a test for the Pythran backend for NumPy expressions.

parent 28cee84e
...@@ -45,6 +45,7 @@ before_script: ccache -s ...@@ -45,6 +45,7 @@ before_script: ccache -s
script: script:
- PYTHON_DBG="python$( python -c 'import sys; print("%d.%d" % sys.version_info[:2])' )-dbg" - PYTHON_DBG="python$( python -c 'import sys; print("%d.%d" % sys.version_info[:2])' )-dbg"
- if $PYTHON_DBG -V >&2; then CFLAGS="-O0 -ggdb" $PYTHON_DBG runtests.py -vv Debugger --backends=$BACKEND; fi - if $PYTHON_DBG -V >&2; then CFLAGS="-O0 -ggdb" $PYTHON_DBG runtests.py -vv Debugger --backends=$BACKEND; fi
- if [ "$BACKEND" = "cpp" ]; then pip install pythran; fi
- CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build_ext -i - CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build_ext -i
- CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv -x Debugger --backends=$BACKEND -j4 - CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv -x Debugger --backends=$BACKEND -j4
......
...@@ -195,7 +195,7 @@ distutils_settings = { ...@@ -195,7 +195,7 @@ distutils_settings = {
} }
def _configure_pythran_extension(ext): def update_pythran_extension(ext):
if not PythranAvailable: if not PythranAvailable:
raise RuntimeError("You first need to install Pythran to use the np_pythran directive.") raise RuntimeError("You first need to install Pythran to use the np_pythran directive.")
pythran_ext = pythran.config.make_extension() pythran_ext = pythran.config.make_extension()
...@@ -842,7 +842,7 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet= ...@@ -842,7 +842,7 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=
m, metadata = create_extension(template, kwds) m, metadata = create_extension(template, kwds)
m.np_pythran = np_pythran or getattr(m, 'np_pythran', False) m.np_pythran = np_pythran or getattr(m, 'np_pythran', False)
if m.np_pythran: if m.np_pythran:
_configure_pythran_extension(m) update_pythran_extension(m)
module_list.append(m) module_list.append(m)
# Store metadata (this will be written as JSON in the # Store metadata (this will be written as JSON in the
...@@ -894,11 +894,13 @@ def cythonize(module_list, exclude=None, nthreads=0, aliases=None, quiet=False, ...@@ -894,11 +894,13 @@ def cythonize(module_list, exclude=None, nthreads=0, aliases=None, quiet=False,
if options.get('cache'): if options.get('cache'):
raise NotImplementedError("common_utility_include_dir does not yet work with caching") raise NotImplementedError("common_utility_include_dir does not yet work with caching")
safe_makedirs(options['common_utility_include_dir']) safe_makedirs(options['common_utility_include_dir'])
pythran_options = None
if PythranAvailable: if PythranAvailable:
pythran_options = CompilationOptions(**options); pythran_options = CompilationOptions(**options)
pythran_options.cplus = True pythran_options.cplus = True
pythran_options.np_pythran = True pythran_options.np_pythran = True
pythran_include_dir = os.path.dirname(pythran.__file__)
c_options = CompilationOptions(**options) c_options = CompilationOptions(**options)
cpp_options = CompilationOptions(**options); cpp_options.cplus = True cpp_options = CompilationOptions(**options); cpp_options.cplus = True
ctx = c_options.create_context() ctx = c_options.create_context()
......
...@@ -114,6 +114,7 @@ def get_distutils_distro(_cache=[]): ...@@ -114,6 +114,7 @@ def get_distutils_distro(_cache=[]):
EXT_DEP_MODULES = { EXT_DEP_MODULES = {
'tag:numpy': 'numpy', 'tag:numpy': 'numpy',
'tag:pythran': 'pythran',
'tag:asyncio': 'asyncio', 'tag:asyncio': 'asyncio',
'tag:pstats': 'pstats', 'tag:pstats': 'pstats',
'tag:posix': 'posix', 'tag:posix': 'posix',
...@@ -611,10 +612,16 @@ class TestBuilder(object): ...@@ -611,10 +612,16 @@ class TestBuilder(object):
languages = list(languages) languages = list(languages)
languages.remove('cpp') languages.remove('cpp')
pythran_dir = self.pythran_dir
if 'pythran' in tags['tag'] and not pythran_dir and 'cpp' in languages:
import pythran.config
pythran_ext = pythran.config.make_extension()
pythran_dir = pythran_ext['include_dirs'][0]
preparse_list = tags.get('preparse', ['id']) preparse_list = tags.get('preparse', ['id'])
tests = [ self.build_test(test_class, path, workdir, module, tags, language, tests = [ self.build_test(test_class, path, workdir, module, tags, language,
expect_errors, expect_warnings, warning_errors, preparse, expect_errors, expect_warnings, warning_errors, preparse,
self.pythran_dir if language == "cpp" else None) pythran_dir if language == "cpp" else None)
for language in languages for language in languages
for preparse in preparse_list ] for preparse in preparse_list ]
return tests return tests
...@@ -885,15 +892,6 @@ class CythonCompileTestCase(unittest.TestCase): ...@@ -885,15 +892,6 @@ class CythonCompileTestCase(unittest.TestCase):
if extra_extension_args is None: if extra_extension_args is None:
extra_extension_args = {} extra_extension_args = {}
if self.pythran_dir is not None:
ext_compile_flags.extend([
'-I', self.pythran_dir,
'-DENABLE_PYTHON_MODULE',
'-std=c++11',
'-D__PYTHRAN__=%d' % sys.version_info.major,
'-Wno-cpp',
])
related_files = self.related_files(test_directory, module) related_files = self.related_files(test_directory, module)
self.copy_files(test_directory, workdir, related_files) self.copy_files(test_directory, workdir, related_files)
...@@ -916,6 +914,10 @@ class CythonCompileTestCase(unittest.TestCase): ...@@ -916,6 +914,10 @@ class CythonCompileTestCase(unittest.TestCase):
with open_source_file(pyx_path) as f: with open_source_file(pyx_path) as f:
DistutilsInfo(f).apply(extension) DistutilsInfo(f).apply(extension)
if self.pythran_dir:
from Cython.Build.Dependencies import update_pythran_extension
update_pythran_extension(extension)
for matcher, fixer in list(EXT_EXTRAS.items()): for matcher, fixer in list(EXT_EXTRAS.items()):
if isinstance(matcher, str): if isinstance(matcher, str):
# lazy init # lazy init
...@@ -2122,7 +2124,7 @@ def runtests(options, cmd_args, coverage=None): ...@@ -2122,7 +2124,7 @@ def runtests(options, cmd_args, coverage=None):
options.cython_only, languages, test_bugs, options.cython_only, languages, test_bugs,
options.fork, sys.version_info[0], options.fork, sys.version_info[0],
options.test_determinism, options.test_determinism,
common_utility_dir, options.pythran_dir) common_utility_dir)
sys.stderr.write("Including CPython regression tests in %s\n" % sys_pyregr_dir) sys.stderr.write("Including CPython regression tests in %s\n" % sys_pyregr_dir)
test_suite.addTest(filetests.handle_directory(sys_pyregr_dir, 'pyregr')) test_suite.addTest(filetests.handle_directory(sys_pyregr_dir, 'pyregr'))
......
# mode: run
# tag: pythran, numpy, cpp
# cython: np_pythran=True
import numpy as np
cimport numpy as cnp
def test():
"""
>>> u = test()
>>> count_non_zero = np.sum(u > 0)
>>> 15000 < count_non_zero < (2**7) * (2**7) or count_non_zero
True
"""
lx, ly = (2**7, 2**7)
u = np.zeros([lx, ly], dtype=np.double)
u[lx // 2, ly // 2] = 1000.0
diffuse_numpy(u, 500)
return u
def diffuse_numpy(cnp.ndarray[double, ndim=2] u, int N):
"""
Apply Numpy matrix for the Forward-Euler Approximation
"""
cdef cnp.ndarray[double, ndim=2] temp = np.zeros_like(u)
mu = 0.1
for n in range(N):
temp[1:-1, 1:-1] = u[1:-1, 1:-1] + mu * (
u[2:, 1:-1] - 2 * u[1:-1, 1:-1] + u[0:-2, 1:-1] +
u[1:-1, 2:] - 2 * u[1:-1, 1:-1] + u[1:-1, 0:-2])
u[:, :] = temp[:, :]
temp[:, :] = 0.0
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment