diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000000000000000000000000000000000..4ec3f4456ed1bbdb63b6b71a550099ab6d4e61d0 --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +max-line-length=120 +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..fce0b7c9c4914ea7346bcf84a85e85b8c6cac86d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,9 @@ + +tests: + image: i10git.cs.fau.de:5005/software/pystencils/full + script: + - pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils + - python3 setup.py test + tags: + - docker + - AVX diff --git a/pystencils_walberla_tests/__init__.py b/pystencils_walberla_tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pystencils_walberla_tests/test_packinfo_generation.py b/pystencils_walberla_tests/test_packinfo_generation.py index 38a3bd670b99f30d4d38b7996a492ff802877c35..f0cf9a2acfe92427e9468f8295991f232f8819b2 100644 --- a/pystencils_walberla_tests/test_packinfo_generation.py +++ b/pystencils_walberla_tests/test_packinfo_generation.py @@ -1,9 +1,14 @@ import pystencils as ps from pystencils_walberla import generate_pack_info_for_field, generate_pack_info_from_kernel from pystencils_walberla.cmake_integration import ManualCodeGenerationContext +import unittest -def test_packinfo_walberla_gen(): - for openmp in (False, True): + +class PackinfoGenTest(unittest.TestCase): + + @staticmethod + def test_packinfo_walberla_gen(): + for openmp in (False, True): for da in (False, True): with ManualCodeGenerationContext(openmp=openmp, double_accuracy=da) as ctx: dtype = "float64" if ctx.double_accuracy else "float32" @@ -29,4 +34,3 @@ def test_packinfo_walberla_gen(): assert 'float ' not in file_to_test else: assert 'double ' not in file_to_test - diff --git a/pystencils_walberla_tests/test_walberla_gen.py b/pystencils_walberla_tests/test_walberla_gen.py index 34ac10b7766831f8a106cc396e3ee7aed46b8b5b..e1caa37e1746f4544693d0942b5c2e6078f225e7 100644 --- a/pystencils_walberla_tests/test_walberla_gen.py +++ b/pystencils_walberla_tests/test_walberla_gen.py @@ -2,49 +2,49 @@ import sympy as sp import pystencils as ps from pystencils_walberla import generate_sweep from pystencils_walberla.cmake_integration import ManualCodeGenerationContext +import unittest -try: - import pycuda -except ImportError: - pycuda = None +class CodegenTest(unittest.TestCase): -for openmp in (False, True): - for da in (False, True): - with ManualCodeGenerationContext(openmp=openmp, double_accuracy=da) as ctx: - h = sp.symbols("h") + @staticmethod + def test_codegen(): + for openmp in (False, True): + for da in (False, True): + with ManualCodeGenerationContext(openmp=openmp, double_accuracy=da) as ctx: + h = sp.symbols("h") - dtype = "float64" if ctx.double_accuracy else "float32" + dtype = "float64" if ctx.double_accuracy else "float32" - # ----- Jacobi 2D - created by specifying weights in nested list -------------------------- - src, dst = ps.fields("src, src_tmp: {}[2D]".format(dtype)) - stencil = [[0, -1, 0], - [-1, 4, -1], - [0, -1, 0]] - assignments = ps.assignment_from_stencil(stencil, src, dst, normalization_factor=4 * h**2) - generate_sweep(ctx, 'JacobiKernel2D', assignments, field_swaps=[(src, dst)]) + # ----- Jacobi 2D - created by specifying weights in nested list -------------------------- + src, dst = ps.fields("src, src_tmp: {}[2D]".format(dtype)) + stencil = [[0, -1, 0], + [-1, 4, -1], + [0, -1, 0]] + assignments = ps.assignment_from_stencil(stencil, src, dst, normalization_factor=4 * h ** 2) + generate_sweep(ctx, 'JacobiKernel2D', assignments, field_swaps=[(src, dst)]) - # ----- Jacobi 3D - created by using kernel_decorator with assignments in '@=' format ----- - src, dst = ps.fields("src, src_tmp: {}[3D]".format(dtype)) + # ----- Jacobi 3D - created by using kernel_decorator with assignments in '@=' format ----- + src, dst = ps.fields("src, src_tmp: {}[3D]".format(dtype)) - @ps.kernel - def kernel_func(): - dst[0, 0, 0] @= (src[1, 0, 0] + src[-1, 0, 0] + - src[0, 1, 0] + src[0, -1, 0] + - src[0, 0, 1] + src[0, 0, -1]) / (6 * h ** 2) + @ps.kernel + def kernel_func(): + dst[0, 0, 0] @= (src[1, 0, 0] + src[-1, 0, 0] + + src[0, 1, 0] + src[0, -1, 0] + + src[0, 0, 1] + src[0, 0, -1]) / (6 * h ** 2) - generate_sweep(ctx, 'JacobiKernel3D', kernel_func, field_swaps=[(src, dst)]) + generate_sweep(ctx, 'JacobiKernel3D', kernel_func, field_swaps=[(src, dst)]) - expected_files = ('JacobiKernel3D.cpp', 'JacobiKernel3D.h', - 'JacobiKernel2D.cpp', 'JacobiKernel2D.h') - assert all(e in ctx.files for e in expected_files) + expected_files = ('JacobiKernel3D.cpp', 'JacobiKernel3D.h', + 'JacobiKernel2D.cpp', 'JacobiKernel2D.h') + assert all(e in ctx.files for e in expected_files) - for file_name_to_test in ('JacobiKernel3D.cpp', 'JacobiKernel2D.cpp'): - file_to_test = ctx.files[file_name_to_test] - if openmp: - assert '#pragma omp parallel' in file_to_test + for file_name_to_test in ('JacobiKernel3D.cpp', 'JacobiKernel2D.cpp'): + file_to_test = ctx.files[file_name_to_test] + if openmp: + assert '#pragma omp parallel' in file_to_test - if da: - assert 'float ' not in file_to_test - else: - assert 'double ' not in file_to_test + if da: + assert 'float ' not in file_to_test + else: + assert 'double ' not in file_to_test diff --git a/setup.py b/setup.py index 482b45ebec8171acb0d396d392b55d1550bd664c..056df54d2848918e2acd43f6d866977c71270fff 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,39 @@ -import os -import sys -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 +from setuptools import setup +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 setup(name='pystencils_walberla', - version=get_current_dev_version_from_git(), + version=version_number_from_git(), description='pystencils code generation for waLBerla apps', author='Martin Bauer', license='AGPLv3', @@ -15,4 +42,5 @@ setup(name='pystencils_walberla', packages=['pystencils_walberla'], install_requires=['pystencils[alltrafos]', 'jinja2'], package_data={'pystencils_walberla': ['templates/*']}, + test_suite='pystencils_walberla_tests', )