diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000000000000000000000000000000000..47db81d63d258bb791cfc8dbd7176492fd9c496f --- /dev/null +++ b/.flake8 @@ -0,0 +1,6 @@ +[flake8] +max-line-length=120 +exclude=pystencils/jupytersetup.py, + pystencils/plot2d.py + pystencils/session.py +ignore = W293 W503 W291 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..73c1ace7cf8cf1d79984375aa3f6db811804a3be --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +__pycache__ +.ipynb_checkpoints +.coverage +*.pyc +*.vti +/build +/dist +/*.egg-info +.cache +_build +/.idea +.cache +_local_tmp \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..dcb0ef62e71da29674eb056d1782bc62ecc15aa9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,133 @@ +stages: + - test + - deploy + + +# -------------------------- Tests ------------------------------------------------------------------------------------ + +# Normal test - runs on every commit all but "long run" tests +tests-and-coverage: + stage: test + except: + variables: + - $ENABLE_NIGHTLY_BUILDS + image: i10git.cs.fau.de:5005/software/pystencils/full + script: + - export NUM_CORES=$(nproc --all) + - mkdir -p ~/.config/matplotlib + - echo "backend:template" > ~/.config/matplotlib/matplotlibrc + - mkdir public + - py.test -v -n $NUM_CORES --cov-report html --cov-report term --cov=. -m "not longrun" + tags: + - docker + - cuda + - AVX + artifacts: + when: always + paths: + - coverage_report + +# Nightly test - runs "long run" jobs only +test-longrun: + stage: test + only: + variables: + - $ENABLE_NIGHTLY_BUILDS + image: i10git.cs.fau.de:5005/software/pystencils/full + script: + - export NUM_CORES=$(nproc --all) + - mkdir -p ~/.config/matplotlib + - echo "backend:template" > ~/.config/matplotlib/matplotlibrc + - py.test -v -n $NUM_CORES --cov-report html --cov-report term --cov=. + tags: + - docker + - cuda + - AVX + artifacts: + paths: + - coverage_report + +# Minimal tests in windows environment +minimal-windows: + stage: test + except: + variables: + - $ENABLE_NIGHTLY_BUILDS + tags: + - win + script: + - source /cygdrive/c/Users/build/Miniconda3/Scripts/activate + - source activate pystencils_dev + - env + - conda env list + - python -c "import numpy" + - python setup.py quicktest + +minimal-ubuntu: + stage: test + except: + variables: + - $ENABLE_NIGHTLY_BUILDS + image: i10git.cs.fau.de:5005/software/pystencils/minimal_ubuntu + script: + - python3 setup.py quicktest + tags: + - docker + +minimal-conda: + stage: test + except: + variables: + - $ENABLE_NIGHTLY_BUILDS + image: i10git.cs.fau.de:5005/software/pystencils/minimal_conda + script: + - python setup.py quicktest + tags: + - docker + + +# -------------------- Linter & Documentation -------------------------------------------------------------------------- + + +flake8-lint: + stage: test + except: + variables: + - $ENABLE_NIGHTLY_BUILDS + image: i10git.cs.fau.de:5005/software/pystencils/full + script: + - flake8 pystencils + tags: + - docker + - cuda + + +build-documentation: + stage: test + image: i10git.cs.fau.de:5005/software/pystencils/full + script: + - export PYTHONPATH=`pwd` + - mkdir html_doc + - sphinx-build -W -b html doc html_doc + tags: + - docker + - cuda + artifacts: + paths: + - html_doc + + +pages: + image: i10git.cs.fau.de:5005/software/pystencils/full + stage: deploy + script: + - ls -l + - mv coverage_report html_doc + - mv html_doc public # folder has to be named "public" for gitlab to publish it + artifacts: + paths: + - public + tags: + - docker + only: + - master@software/pystencils diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000000000000000000000000000000000000..5a7ce065a9888d02faf36c9d9f3c3c279dce865d --- /dev/null +++ b/conftest.py @@ -0,0 +1,129 @@ +import os +import pytest +import tempfile +import runpy +import sys +# Trigger config file reading / creation once - to avoid race conditions when multiple instances are creating it +# at the same time +from pystencils.cpu import cpujit + +# trigger cython imports - there seems to be a problem when multiple processes try to compile the same cython file +# at the same time +try: + import pyximport + pyximport.install(language_level=3) +except ImportError: + pass +from pystencils.boundaries.createindexlistcython import * # NOQA + + +SCRIPT_FOLDER = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.abspath('pystencils')) + + +def add_path_to_ignore(path): + if not os.path.exists(path): + return + global collect_ignore + collect_ignore += [os.path.join(SCRIPT_FOLDER, path, f) for f in os.listdir(os.path.join(SCRIPT_FOLDER, path))] + + +collect_ignore = [os.path.join(SCRIPT_FOLDER, "doc", "conf.py")] +add_path_to_ignore('pystencils_tests/benchmark') +add_path_to_ignore('_local_tmp') + + +try: + import pycuda +except ImportError: + collect_ignore += [os.path.join(SCRIPT_FOLDER, "pystencils/pystencils_tests/test_cudagpu.py")] + add_path_to_ignore('pystencils/gpucuda') + +try: + import llvmlite +except ImportError: + collect_ignore += [os.path.join(SCRIPT_FOLDER, 'pystencils_tests/backends/llvm.py')] + add_path_to_ignore('pystencils/llvm') + +try: + import kerncraft +except ImportError: + collect_ignore += [os.path.join(SCRIPT_FOLDER, "pystencils_tests/test_kerncraft_coupling.py")] + add_path_to_ignore('pystencils/kerncraft_coupling') + +try: + import blitzdb +except ImportError: + add_path_to_ignore('pystencils/runhelper') + + +collect_ignore += [os.path.join(SCRIPT_FOLDER, 'setup.py')] + +for root, sub_dirs, files in os.walk('.'): + for f in files: + if f.endswith(".ipynb") and not any(f.startswith(k) for k in ['demo', 'tutorial', 'test', 'doc']): + collect_ignore.append(f) + + +import nbformat +from nbconvert import PythonExporter + + +class IPythonMockup: + def run_line_magic(self, *args, **kwargs): + pass + + def run_cell_magic(self, *args, **kwargs): + pass + + def magic(self, *args, **kwargs): + pass + + def __bool__(self): + return False + + +class IPyNbTest(pytest.Item): + def __init__(self, name, parent, code): + super(IPyNbTest, self).__init__(name, parent) + self.code = code + self.add_marker('notebook') + + def runtest(self): + global_dict = {'get_ipython': lambda: IPythonMockup(), + 'is_test_run': True} + + # disable matplotlib output + exec("import matplotlib.pyplot as p; " + "p.switch_backend('Template')", global_dict) + + # in notebooks there is an implicit plt.show() - if this is not called a warning is shown when the next + # plot is created. This warning is suppressed here + exec("import warnings;" + "warnings.filterwarnings('ignore', 'Adding an axes using the same arguments as a previous.*')", + global_dict) + with tempfile.NamedTemporaryFile() as f: + f.write(self.code.encode()) + f.flush() + runpy.run_path(f.name, init_globals=global_dict, run_name=self.name) + + +class IPyNbFile(pytest.File): + def collect(self): + exporter = PythonExporter() + exporter.exclude_markdown = True + exporter.exclude_input_prompt = True + + notebook_contents = self.fspath.open() + notebook = nbformat.read(notebook_contents, 4) + code, _ = exporter.from_notebook_node(notebook) + yield IPyNbTest(self.name, self, code) + + def teardown(self): + pass + + +def pytest_collect_file(path, parent): + glob_exprs = ["*demo*.ipynb", "*tutorial*.ipynb", "test_*.ipynb"] + if any(path.fnmatch(g) for g in glob_exprs): + return IPyNbFile(path, parent) diff --git a/doc/conf.py b/doc/conf.py index a71c41e781d07c70990ce446042ee2947f25b114..de898facf492671b8290c1d0ff3e9ffb2ca605e0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,12 +1,59 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # +import datetime +import sphinx_rtd_theme import os import sys -sys.path.insert(0, os.path.abspath('..')) -sys.path.insert(0, os.path.abspath('../..')) -from sphinx_doc_conf import * +sys.path.insert(0, os.path.abspath('.')) +from version_from_git import version_number_from_git + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.mathjax', + 'sphinx.ext.napoleon', + 'nbsphinx', + 'sphinxcontrib.bibtex', + 'sphinx_autodoc_typehints', +] + +add_module_names = False +templates_path = ['_templates'] +source_suffix = '.rst' +master_doc = 'index' + +copyright = '{}, Martin Bauer'.format(datetime.datetime.now().year) +author = 'Martin Bauer' +version = version_number_from_git() +release = version_number_from_git() +language = None +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints'] +default_role = 'any' +pygments_style = 'sphinx' +todo_include_todos = False + +# Options for HTML output + +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +html_theme = 'sphinx_rtd_theme' +htmlhelp_basename = 'pystencilsdoc' +html_sidebars = {'**': ['globaltoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html']} + +# NbSphinx configuration +nbsphinx_execute = 'never' +nbsphinx_codecell_lexer = 'python3' + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'python': ('https://docs.python.org/3.6', None), + 'numpy': ('https://docs.scipy.org/doc/numpy/', None), + 'matplotlib': ('https://matplotlib.org/', None), + 'sympy': ('https://docs.sympy.org/latest/', None), + } + +autodoc_member_order = 'bysource' project = 'pystencils' html_logo = "img/logo.png" diff --git a/doc/version_from_git.py b/doc/version_from_git.py new file mode 100644 index 0000000000000000000000000000000000000000..2b7d0713b901466d178c6d8eaf71dd59f1c6bb77 --- /dev/null +++ b/doc/version_from_git.py @@ -0,0 +1,31 @@ +import subprocess + +def version_number_from_git(tag_prefix='release/', sha_length=10, version_format="{version}.dev{commits}+{sha}"): + + def get_released_versions(): + tags = sorted(subprocess.getoutput('git tag').split('\n')) + versions = [t[len(tag_prefix):] for t in tags if t.startswith(tag_prefix)] + return versions + + def tag_from_version(v): + return tag_prefix + v + + def increment_version(v): + parsed_version = [int(i) for i in v.split('.')] + parsed_version[-1] += 1 + return '.'.join(str(i) for i in parsed_version) + + latest_release = get_released_versions()[-1] + commits_since_tag = subprocess.getoutput('git rev-list {}..HEAD --count'.format(tag_from_version(latest_release))) + sha = subprocess.getoutput('git rev-parse HEAD')[:sha_length] + is_dirty = len(subprocess.getoutput("git status --untracked-files=no -s")) > 0 + + if int(commits_since_tag) == 0: + version_string = latest_release + else: + next_version = increment_version(latest_release) + version_string = version_format.format(version=next_version, commits=commits_since_tag, sha=sha) + + if is_dirty: + version_string += ".dirty" + return version_string diff --git a/pystencils_tests/test_datahandling.py b/pystencils_tests/test_datahandling.py index 0710fb249f71bdc0684da069922a0c7ce4601c6f..887c855dbb1c0be11847f0d3a34f849edea08ce9 100644 --- a/pystencils_tests/test_datahandling.py +++ b/pystencils_tests/test_datahandling.py @@ -1,7 +1,6 @@ import numpy as np import os from tempfile import TemporaryDirectory - import pystencils as ps from pystencils import create_kernel, create_data_handling @@ -196,11 +195,15 @@ def test_kernel(): for domain_shape in [(4, 5), (3, 4, 5)]: dh = create_data_handling(domain_size=domain_shape, periodicity=True) kernel_execution_jacobi(dh, test_gpu=True) - - dh = create_data_handling(domain_size=domain_shape, periodicity=True) - kernel_execution_jacobi(dh, test_gpu=False) reduction(dh) + try: + import pycuda + dh = create_data_handling(domain_size=domain_shape, periodicity=True) + kernel_execution_jacobi(dh, test_gpu=False) + except ImportError: + pass + def test_vtk_output(): for domain_shape in [(4, 5), (3, 4, 5)]: diff --git a/pystencils_tests/test_fd_derivation.ipynb b/pystencils_tests/test_fd_derivation.ipynb index 144bf19487056c2e9e363b6ec0baf828fa158227..50ff9e1015b8c3e1983185b3be8f007383dfcabe 100644 --- a/pystencils_tests/test_fd_derivation.ipynb +++ b/pystencils_tests/test_fd_derivation.ipynb @@ -2,13 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "from lbmpy.session import *\n", - "from lbmpy.phasefield.scenarios import *\n", - "import pystencils as ps\n", + "from pystencils.session import *\n", "from pystencils.fd.derivation import *" ] }, @@ -21,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -36,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -45,7 +43,7 @@ "Finite difference stencil of accuracy 2, isotropic error: False" ] }, - "execution_count": 16, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -58,12 +56,12 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGkAAABLCAMAAABEOFk1AAAAPFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMAMquZdlQQQOkwRIlmzd0i77ts7uXj/QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAkpJREFUWAntmduagyAMhBGU7YrH5f3fdQW2mkmrpqv2oh9etIDj/JJGi1EVPm5aXbV1CaBU4U05bdVVINUEe+0DqbgMshg3QLLGNU6AFepAhqR2iqDt+uVEVlpCHciA1AzB2bUr/vOwUIcyII0x/SpvZ8/nDaEOZUDykVT7vSwU6lBGSdabMIfal8+nch8V6piMknrvglmRvu6+j99CHZMhKc5JQBLp+hSiux0lsek+TuZvRKhjMkpS6SeshBmxq0M7II1jOOtmP8tlOrQDUrrUjPDK3dWhHZBUF+5Gw/6NT6gDGZKsm+7u+yAl1IEMSavpdsKOTDoSxBy9HD2MQM4IjIfqjRlHwW0yHsajVw17S7CFZsNSyvl6GXloETsgWW307t/g4qbjSQ1xObqMLi20A9IkKl8gDV1w1VvPD8TuCKmNZ/UOUopTtxWFk+YUSfXmOvRMUrf50PpPkm27eWv/LiMTl7Mpjk8+Genr9j2LyK55bKNRboNoKv/c8Dn3NVIVQP3GMySxO5LlqogzKq8n9Z1zzuh4/a5EeHVORg++1c3KYXy4TQWNdRLY8ehxt/P6mXQkljl6OXoYgc/PCCgy4uShJ9SBDKMHRUbwxo5QBzIgYZERzWlPqEMZkLDISL2xLdShDEhYZER32hPqUEZJrExGvaEt1DEZJbEiI7jTjlDHZEiKK5B7kZGaQ5sVI2Ef6TAZJbHpkoOwKdQxGSXlmqXKNcupkIxPAJhlZ/Yy6Ug0Pzd673pzbMOL3bLcqjQd+YGmdzIJoH4B+tMpKpuC5nwAAAAASUVORK5CYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGkAAABLCAMAAABEOFk1AAAAPFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMAMquZdlQiEEDpMESJZs3d77ts6LWnRAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAj9JREFUWAntmV17gyAMRlFQ1olf4///1wl0kpc+Qlba3QxvBnKas6TUaio6649evOtYg0CIzkp1HMO7RGJ24XvrTOPbJDHwgCajZtPF1csRk6MYmpajgnotZ8jkAAPTvLkkzHKZyn2BySEGpt1vv8HqgorJIQYm602TLe1CJocYNWkrXTKTVfmcmFyCUdNojVN0JROTSzA0+Zy6ILzOawy5l7gEo6Yk3UsVk0swahLhLRyYO6LIYTgw7bvLYy7vch6H4cCEH7XL6gkmhxiYxOquRlv5wsfkAEOTNsfVvSwSTA4wNF0XrH6lmWpq2KrXqocVaDsC6yG0lPvOuEz6l6XVG7bSLVi0aXcrZewUzzyMSDgw6d70xa/BGE36f2rzt6PxbBxhODAdUPkLN0baVjfuc88PJFyNafH59zbzTr3IFLJbc/V+pWnK3h2+0rRmH1qfNOmFHPc3R/rb3rhLklFi+rh9ngBZOs9lBiovolv564bPub8zDU40Zp4hSbiaXS46/2yinjOp3J5NyjiuxhjZ+89vsvQzJeEwJ9lvdpHzD1f4u4SGxrUJwqGpELpquZlqyteq16qHFfgHO4I2GTF5nDE5imH1oMmIsWHG5AADE7YqIDZMmBxiYMImIwSHCZNDDEzYZITgMGFyiFFT0iaD4HTC5BKMmpImIw0OYyaXYGhqPctSb7P1LGHTnRNoRp5nHwaA0b13dEZbz/KhXLkTWL0cWbvWTDUVDNX7q1+OtfthV6lcp6kmmaNFFATiG+4bKVe2WSLVAAAAAElFTkSuQmCC\n", "text/latex": [ "$$\\left[\\begin{matrix}0 & 0 & 0\\\\1 & -2 & 1\\\\0 & 0 & 0\\end{matrix}\\right]$$" ], @@ -75,7 +73,7 @@ "⎣0 0 0⎦" ] }, - "execution_count": 17, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -95,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -104,13 +102,13 @@ "Finite difference stencil of accuracy 2, isotropic error: True" ] }, - "execution_count": 19, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "stencil = get_stencil(\"D2Q9\")\n", + "stencil = [(i, j) for i in (-1, 0, 1) for j in (-1, 0, 1)]\n", "isotropic_2d_00 = FiniteDifferenceStencilDerivation((0,0), stencil)\n", "isotropic_2d_00_res = isotropic_2d_00.get_stencil(isotropic=True)\n", "assert isotropic_2d_00_res.is_isotropic\n", @@ -120,12 +118,12 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAIIAAABNCAMAAABdY0yuAAAAXVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXQA/SAAAAHnRSTlMAMquZdlQQQOkwRM3d7yKJu2aF48P7apvf8VzR02ydbYKKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADz0lEQVRoBe2a6XbbIBCF0VpXq92kbdJF7/+YAUlIwNyBIUtPc475YUto5s5nhIERUiosRR/WiM5lbhKroioHUUjfSObGWBXLWspDsnkNglIyN9dq2CIrVSxVrUvz7xFuJm65GITiiL4euKD+leiZzI1Y3e4IulnvrWD6Fm6FMdrtuIuNyI1YAYSpGpay5uKw9TI3YAUQ2CAfdOHzIrT9cJQ+GNhyG8tvhW3Idj7lcocT63JY2IPd0kdg3T/yAkHYp/O5ulZtZuB5rm9xFygeINjpfJ6UKjMXLn2npujIwIgHCHbSHzRCsegPean1eqNNDCfbLBmIcwidUtOiP+RlPNcbrNOO4IszCEakWbI6w9LUdar7nGsFRzyCMCRa1f+t01Ip1SVWfCeCI84jzFoyo7SLuRGJe3cguOIswi2PYI++xP+VFsET5xC6WTdr1sjbm+iyVvDFKcJYlMX07aFpmmtWd/xxKaafD/Fb1yDxAMFM5496DP++juNxveBqp12eotCMeIBgZLumiCoFoe2pzA1YIYSsEckSqE7kBqwQgs6tUmPMEfg86ERuwAogTPrn3K6ntvBI5gasAIIJmTlFWUqZW2AFEErdGdvEH9zGdL5lbsAKIIx6jp7ypihDInMDVgBh1q3gjuHOL40dytyAFUBQ81zp4Tm7yNyoFULIDv42h8+L8N6pzJfLV6cpbaKhH7/kFJkbsvp7Ac+ackK/3Rb2hXROggLPdWUGnlQh4gghmZPAKJVeNVXpqYWKAwRJTgIgzFhi1OIFiAMESU7CxEm3AhAHCJKcBCO0Y3LBC8QpgigngQh1n0x+kDhFEOUkEEHQHZE4RdhygUROwiBMa0rFXFyr13WILw4QJDkJjbL2g8kXp1YKiAOE7lr0TebjDR1smIq+HlNjExAHCMXj0/MrVtC/fv95LpMPRYA4QLBPWkAzxqts0pppdUcwDXZvhXsr2D8O7gvRh6jWlXyT/RZiYSqIFUAAGydQK6iUuQErgBBIf/jp50V471Tm3LM+Mg17IL8L1oNfwB4W9mAX/x9vBNw4kTUGSVKIGxQPWoHZOCFaqIImKYEVIx4g2LVCsHESaMFTkKQQu21FEYhzCP7GCdECFSBJIVY7gi/OIBhnZ+OEaIEKkKQQq3Nd5YhHEJyNE6JFK1CSQqxOBEecR8h86IaSFB7BFWcRvI0TogUqQJJCrGwreOIcgr9xQrRABUhSiNWO4ItvCOuQub1atU3nOpnJ3ZXp9OONVAYUih+vVrXmBae6NvsJdjofVyjyK6IVt2qOZ0BUfH21qq7VC3XOS/my1/oRAAAAAElFTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAIIAAABNCAMAAABdY0yuAAAAYFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACGXEAAAAH3RSTlMAMquZdlQiEEDpMES73YnNZu+F48P7apvf1/Fc0cls39hR/gAAAAlwSFlzAAAOxAAADsQBlSsOGwAAA8dJREFUaAXtmumW2yAMhcFrU6/pdJ0ufv+3LNjGBnQBkcn0NOfEPxIbpMsXGQMyEcI/ZO+XsK55bhwrWZYDq0nXiOcWsJLLehSHZHcLghA8N9tq2FoWQi5lpY763yPMut1i0QjN0fp6YoO6NdErnhuxqp8IKqzPKOi+BaNQ3/ZQ8tyIFUBoymEpqmjfR5U8N2AFEJD+e5Y9LkI7WYd8W4zcKGxDtvXJFz+cgi6HhTnZLV2EoPt7VhCEfTofy75sMxsex2qOu0BxD8FM56OauIoprufXTp1orn6hfR0Q9xDMpD8oBDKB2nL0vFLrjTYxnGyzpCceQuiEaBb1wT+u53oj6LQjuOIBBC1SL1mdYamrKtV9zrWCJR5BGBJRdX9rs4zmLroV9tWJYImHEcbSdk6et+ttS9y7A8EWDyLMeQRCbAjxp9IgOOIhhE6HNWvknXTrvCi44gShHmQhm08vdV33Wd3x60U2317iNwyKewh6Ov+sxvAv6zge1/NqO+XyPQodEPcQtGxXy6iS17S55LkBK4SQ1QUMAbPngP6FEFRulRpjjobPk47lBqwAQqPGzzk/t+a5ASuAoH9Y5hRlYsFz86wAgr4J21hnlFnfPDdgBRCuaqJu8qYozchzA1YAYVRRsMdwVgyUC8sNWAEEMY6lGp6zD54btUII2Y2/zeFxEe6dyny4fLRCaRIN9fol5+C5Ias/l5vHoRzAmC3sC+mcBEmOVVkwplgijhCSOQkCEKVaNZXpqYWKAwROTgIg9FgyJzsQEAcInJwEIOiidBSAOEDg5CQYob0mVztAnCKwchKIUE3J5AeJUwRWTgIRGDcCiVMEVk4SQGiWVG4LEh6AwMlJKMLaD5olnk0JAcQBQtfLvs58vaGQhkb28zU1NgFxgCD7H683rKB//vr9Wni7CjRYQBwgpHN0qryWmKQ1UL0XE6sngo7MMwrPKOxPCO4LZOPEWMe/eW7ECnRHsHESb3qr5bkBK4DAae+eNo+LcO9U5nzlcGQa5oQfcOMRXsAeFuZkF/8fbwTcOOEFgyQpxA2Ke1EIbJwQLVRAkxTPKiDuIZi1grdx4mnBS5CkELttreCJhxDcjROiBQpAkkKsdgRXPICgna2NE6IFCkCSQqzOFZMlHkGwNk6IFi1ASQqxOhEs8TBC5ks3lKSEEWzxIIKzcUK0QAFIUoiViYIjHkJwN06IFigASQqx2hFc8Q1hHTK3v1Zt07mcsndlOvV6I5UB+eLHX6ta/QenqlKPijDT+XWFIr8iWlCXYzwDouLrX6uqSvwFDr5NBGUlpz0AAAAASUVORK5CYII=\n", "text/latex": [ "$$\\left[\\begin{matrix}\\frac{1}{12} & - \\frac{1}{6} & \\frac{1}{12}\\\\\\frac{5}{6} & - \\frac{5}{3} & \\frac{5}{6}\\\\\\frac{1}{12} & - \\frac{1}{6} & \\frac{1}{12}\\end{matrix}\\right]$$" ], @@ -137,7 +135,7 @@ "⎣1/12 -1/6 1/12⎦" ] }, - "execution_count": 20, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -148,17 +146,19 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "<Figure size 144x144 with 1 Axes>" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -169,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -186,12 +186,12 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHoAAABNCAMAAABe+IDDAAAAV1BMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcPecEAAAAHHRSTlMAMquZdlQQQOkwRM3d7yKJZrvh0Xzfvadc0/FsqyZmNQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAA5lJREFUaAXtmtmanCAQhVHQmbh2Z7LH93/OsAxanBapyjhJ50t7oXRTdX7B7YAqRZeqp79K5VlfdVsK2uqPxCtdD1tksTRPStXsfd0Rrxa/1J7USNCDRVeLXTGXKD4EokvWxi7Nb6A7pabFrphLRF8cr14cutpSY+32T6HULPyDnYhf3oweTGHfSPW56FkT6VLxVPRFQlZnortZqY6cKYVmF9BjIZ1WV33TNFfBaUbF4TSb9LDU/PNm9Ncn3ZmjMogD+ijz7LoHWqlwa7VrXufKwjH6njp8ns2F12YXNRtd868tlYhjq/tOTfTiO94LbfdSX49jSG0qDmhjH9ot/7rW9mbmFHgLiAN6DA9tnlSI4rcaxAG9NMZIzJbto5F9CwfxFD0t9kHUSSyS6dmHB8VTdLu4Dhc4HhvN7nAUT9GBugiuLufNuOeHb9ImDujeUdmt9sd52sTCeZddgzigu4/6en3JJmOFM8NmfApO3MzGXmsHC4gDev6k5898dGVpX76GUcPFcpvg5TN4EAe01NN7SLA9g7Pjh8YYxBEt9PQbuvVmHu4aafPdzpEBA6BdrMTTb+gw/hlKFwcR30FLPD1FuydYMZcE3KJFnp6i3ahvLNzbqPgNWubpN3Q41oVbQiKOaKGn39CqfIarVBzQUk8f0N5bGPvkOb6uQRzQMk/vwauxn/V8/LwFcUB7sT+0+nfQbT+sS8+2J/vd6Fr99PzhtRJd+n5O8u+aEgtJLf0RA6KN/PkMcyk0+H3LeKyFnj7uHC8tjQK00NNHMi8NohAt8vSRrHhDAYgCtBNjW8yV7Au8NBJ1ixZ4esrmpdGoG7TA01MyLy2JukH/zQ4XeHrabGYaGTCkrRZ6+ojmpWFUilbDVPVm5M8TvL4FCEOBUhqIA/rby/cfNX9qPb4FcEOBchqIA9oaDckQF0x9PADZbSL+RnRq6rPIWHEi2kkSUx8J2e3JaGLqs8hYcS6amvpIyG5PRSemPouMFWeiU1MfCdltAc2fK7TW6vEWINvNmYqbW0om7h3+vhs0uvRCW2XhGH03rbatTCbqC61+vAUodpCd0kxfMcCxPpxy21cnpn4/YP0XxAENE/VrVr5ATX0+yteAeIrGifqClq1OTP1xOIqnaJyoP9YKtewOR/EU/X+9BfD3ODeN3tlXdQ378xo7YnBvAUrWPx62TXz9JKZ1H6gY46bS1aU07xZ1/JZn/deUVdx/EmOM+gXcoENgExPFVQAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHoAAABNCAMAAABe+IDDAAAAVFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwjqETAAAAG3RSTlMAMquZdlQiEEDpMES73Ylmze/h0WzfvadcyfFyvev/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADhklEQVRoBe2a2XqlIBCE8YCajHuSWX3/9xyWg9LlQvfEzPLN8cKNpn5B0AJVKl2KNj3K7fe61XUuaE0/Ey+07tbI7F5fKXUbs2H3gB3xYvbLzUc0EnRn0cVsV8wlineB6DJrY5fyF9CNUtVsV8wlogfHu81w3TGVKaZUOfNvNhEv343uDPsq1bXoXvPJ16IHCflSdNMr1RTscp9XeCnpXMVYlmXLb2ZEHJpZpbv5xm83k++f3EKDOKC5KlfEPdBKhUerXfMqVBaO0X9Thfe9GXhldlG90Td+31JEHEs9Nqqa2Ghtr1LzvQUVB7SxL+2a36+1fZgNzIahFIgDegovbXaxbSC/1CAO6Lk0RmK2bB1N7Ec4iFN0NbvXgeQpbkb27UFxiq692RE4HkmFozhFq4AW9C7nzbjtA8QBPToqu9T+Plcz90pBHNDNi27bV3YDd2Z4mJ5Czza9sS3lZAFxQPdvuv/MRxeW9uVrGDUMllsGL3+AB3FASz29h4Qu0Tk7fmqMQRzRQk+/ouvZ9W94avjkZeUuLhkwANqFSTy9l/WlDuOfLtfkEvEdtMTTp2j3BsvmTQK2aJGnT9Fu1Ddlnm2p+AYt8/QrOtzrzCOBiCNa6OlXtMq3cEXFAS319B4djL2xQ6Dzfg3igJZ5eg9ejL3p0zvp0+gKxAFNYz/26N9B12OysO3Jfu25Uj89f7onokvfz0POLlniDklND2JAtJFvzzCXkgZ/7D7ea6GnjxfHy0ajAC309JHMywZRiBZ5+khWvKEARAHaifE9/YLmZ0vEt2iBp0/RvGxp1AYt8PQpmZeNRG3Qf7LCBZ4+LTYzWzJgoKUWevqI5mXDKIpWXVW0w8SfJ7h/BQhDgVw2EAf0t9fvP278qfX4FcANBfLZQBzQwiEumPp4Aw63ZPz8TjQ19YfImHAh2kkmpj4SDrcXoxNTf4iMCdeiM1YwQsP2UjQx9ZSzc3Qlmpr6HRg9dY4mE/U04/YITP02AM4Qcehci5+HPAeHYOoPouJpEAd0jPod2wf68RWA2c6oqc9menwFsK88Mtw7nXLbr8/E1O8HLGdBHNAwUb/kOt5JTf1xlE8BcYrGifqMlk0mpv48HMUpGifqz7VCKrvCUZyi/6+vAH6aw02jN3ZCv2T/XmNHDO4rQM76x9u2ii+/xNTuBxVj3FS6KnUv+M7Fs/4RvYr7X2KMUT8Bqn5A97SBuwoAAAAASUVORK5CYII=\n", "text/latex": [ "$$\\left[\\begin{matrix}\\frac{1}{6} & \\frac{2}{3} & \\frac{1}{6}\\\\\\frac{2}{3} & - \\frac{10}{3} & \\frac{2}{3}\\\\\\frac{1}{6} & \\frac{2}{3} & \\frac{1}{6}\\end{matrix}\\right]$$" ], @@ -203,7 +203,7 @@ "⎣1/6 2/3 1/6⎦" ] }, - "execution_count": 23, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -217,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -242,7 +242,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/pystencils_tests/test_field_equality.ipynb b/pystencils_tests/test_field_equality.ipynb index 03837702b4d4ea4b1667ea6bbe724f717a69a182..8de31e83b5e496cd57e7e1f7d91a1847588108d8 100644 --- a/pystencils_tests/test_field_equality.ipynb +++ b/pystencils_tests/test_field_equality.ipynb @@ -164,13 +164,13 @@ "output_type": "stream", "text": [ "Field Accesses:\n", - " - f[0], hash 2177071761647211096, offsets (0,), index (), (('f_C', ('commutative', True)), ((0,), (fshape_f[0],), (fstride_f[0],), -2638709558778433189, <FieldType.GENERIC: 0>, 'f'), 0)\n", - " - f[0], hash -219035921004479174, offsets (0,), index (), (('f_C', ('commutative', True)), ((0,), (fshape_f[0],), (fstride_f[0],), 1379426851108887372, <FieldType.GENERIC: 0>, 'f'), 0)\n", + " - f[0], hash -3276894289571194847, offsets (0,), index (), (('f_C', ('commutative', True)), ((0,), (_size_f_0,), (_stride_f_0,), 3146377891102027609, <FieldType.GENERIC: 0>, 'f', None), 0)\n", + " - f[0], hash -1516451775709390846, offsets (0,), index (), (('f_C', ('commutative', True)), ((0,), (_size_f_0,), (_stride_f_0,), -1421177580377734245, <FieldType.GENERIC: 0>, 'f', None), 0)\n", "\n", " -> 0,1 f[0] == f[0]: False\n", "Fields\n", - " - f, 139911303819560, shape (fshape_f[0],), strides (fstride_f[0],), double, FieldType.GENERIC, layout (0,)\n", - " - f, 139911303820008, shape (fshape_f[0],), strides (fstride_f[0],), float, FieldType.GENERIC, layout (0,)\n", + " - f, 140548694371968, shape (_size_f_0,), strides (_stride_f_0,), double, FieldType.GENERIC, layout (0,)\n", + " - f, 140548693963104, shape (_size_f_0,), strides (_stride_f_0,), float, FieldType.GENERIC, layout (0,)\n", "\n", " - f == f: False, ids equal False, hash equal False\n" ] @@ -179,52 +179,6 @@ "source": [ "print_field_accesses_debug(f1.center * f2.center)" ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Custom fields" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "from lbmpy.sparse.update_rule_sparse import *" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEcAAAAgBAMAAACyb3jOAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEJl2IquJVETdZu8yu83OyatpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQVQ4EcWQsUoDQRCGJ6A5CcFAsNDqLGJhF3yC4AukEITgE9iIICmCRV4hjZVIAr6AkDoQ8gByTao0aWwPLZR0OjO7MzdLbkErr7j5d75v93YOwD2vvm6V+lpbi57GMNRPRkVjUMQwJf8jNc86UHonAnKny+FtuUTAS5XNIVjpTsZj4KXkHbv3QgBUYpC8MKmOAM7HF2qpRGDn9LONpHb1cKwCBZEC0CDVPCKBBd25MTCqZMGQnFovY/Umzx/z/I0zgm/XBbjmvLtmgC89CUEq0pJzieSA2zuNSQ6wVNlEJA9Y2vuISB6wVMW7pVmymk14WVzcAR67v49QhyDvwMkCaKKnI+wFknMUkPTcikgC9N+kmfxxf4yU8ReoZLNwqSphw2bhVM3YccluiJ70Zyn4dLD7t4sf071mgtNBAg8AAAAASUVORK5CYII=\n", - "text/latex": [ - "$${{f}_{\\mathbf{{l}_{1}^{1}}}^{1}} + {{f}_{\\mathbf{{l}_{1}}}^{1}}$$" - ], - "text/plain": [ - "f_000035D373 + f_000035D373" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list_field = create_symbolic_list('l', 10, 2, np.float64)\n", - "normal_field = ps.fields(\"f: [2D]\")\n", - "normal_field.field_type = ps.FieldType.CUSTOM\n", - "\n", - "t1 = normal_field.absolute_access( (list_field[1](0),), (1,))\n", - "t2 = normal_field.absolute_access( (list_field[1](1),), (1,))\n", - "t1 + t2" - ] } ], "metadata": { @@ -243,7 +197,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/pystencils_tests/test_finite_differences.py b/pystencils_tests/test_finite_differences.py index dcf9fa2b735c8512424918052c63348b51355cd7..f8784d0e34cb66198639f2d66b6f6d7f98ff0467 100644 --- a/pystencils_tests/test_finite_differences.py +++ b/pystencils_tests/test_finite_differences.py @@ -25,6 +25,7 @@ def test_spatial_2d_unit_sum(): _, coefficients = stencil_coefficients(discretized) assert sum(coefficients) == 0 + def test_spatial_1d_unit_sum(): f = ps.fields("f: double[1D]") h = sp.symbols("h") diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000000000000000000000000000000000000..88de625d43f2fefe3558748698f6746d89ebacc5 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,42 @@ +[pytest] +python_files = test_*.py *_test.py scenario_*.py +norecursedirs = *.egg-info .git .cache .ipynb_checkpoints htmlcov +addopts = --doctest-modules --durations=20 --cov-config pytest.ini + +[run] +branch = True +source = pystencils + pystencils_tests + +omit = doc/* + pystencils_tests/* + setup.py + conftest.py + pystencils/jupytersetup.py + pystencils/cpu/msvc_detection.py + pystencils/sympy_gmpy_bug_workaround.py + pystencils/cache.py + pystencils/pacxx/benchmark.py + +[report] +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + def __repr__ + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + #raise ValueError + + # Don't complain if non-runnable code isn't run: + if 0: + if False: + if __name__ == .__main__.: + +skip_covered = True +fail_under = 74 + +[html] +directory = coverage_report diff --git a/setup.py b/setup.py index 1694c1545f383499ae0d6e6c92571632a22b7b95..a24dafccb0b2afa60cb454a09c3e08c2c5bc3269 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,55 @@ import os import sys +import io from setuptools import setup, find_packages -sys.path.insert(0, os.path.abspath('..')) -from custom_pypi_index.pypi_index import get_current_dev_version_from_git +import distutils +from contextlib import redirect_stdout +from importlib import import_module +sys.path.insert(0, os.path.abspath('doc')) +from version_from_git import version_number_from_git + + +quick_tests = [ + 'test_datahandling.test_kernel', + 'test_blocking_staggered.test_blocking_staggered', + 'test_blocking_staggered.test_blocking_staggered', + 'test_vectorization.test_vectorization_variable_size', +] + + +class SimpleTestRunner(distutils.cmd.Command): + """A custom command to run selected tests""" + + description = 'run some quick tests' + user_options = [] + + @staticmethod + def _run_tests_in_module(test): + """Short test runner function - to work also if py.test is not installed.""" + test = 'pystencils_tests.' + test + mod, function_name = test.rsplit('.', 1) + if isinstance(mod, str): + mod = import_module(mod) + + func = getattr(mod, function_name) + print(" -> %s in %s" % (function_name, mod.__name__)) + with redirect_stdout(io.StringIO()): + func() + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + """Run command.""" + for test in quick_tests: + self._run_tests_in_module(test) setup(name='pystencils', - version=get_current_dev_version_from_git(), + version=version_number_from_git(), description='Python Stencil Compiler based on sympy as numpy', author='Martin Bauer', license='AGPLv3', @@ -14,6 +57,7 @@ setup(name='pystencils', url='https://i10git.cs.fau.de/software/pystencils/', packages=['pystencils'] + ['pystencils.' + s for s in find_packages('pystencils')], install_requires=['sympy>=1.1', 'numpy', 'appdirs', 'joblib'], + package_data={'pystencils': ['include/*.h']}, classifiers=[ 'Development Status :: 4 - Beta', 'Framework :: Jupyter', @@ -31,6 +75,9 @@ setup(name='pystencils', 'doc': ['sphinx', 'sphinx_rtd_theme', 'nbsphinx', 'sphinxcontrib-bibtex', 'sphinx_autodoc_typehints', 'pandoc'], }, - tests_require=['pytest', 'pytest-cov', 'pytest-xdist', 'flake8'], + tests_require=['pytest', 'pytest-cov', 'pytest-xdist', 'flake8', 'nbformat', 'nbconvert', 'ipython'], python_requires=">=3.6", + cmdclass={ + 'quicktest': SimpleTestRunner + } )