Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (56)
[flake8]
max-line-length=120
exclude = src/pystencilssfg/_version.py
......@@ -7,9 +7,10 @@
**/build
# pdm dev environment
# dev environment
**/.venv
.pdm-python
**/venv
**/.nox
# build artifacts
dist
......@@ -17,6 +18,7 @@ dist
*.whl
*.egg-info
# mkdocs
site
\ No newline at end of file
# tests and coverage
.coverage*
htmlcov
coverage.xml
stages:
- pretest
- test
- "Code Quality"
- "Tests"
- "Documentation"
- deploy
linter:
stage: pretest
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
script:
- flake8 src/pystencilssfg
.nox-base:
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine
tags:
- docker
linter:
extends: .nox-base
stage: "Code Quality"
needs: []
script:
- nox --session lint
typechecker:
stage: pretest
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
extends: .nox-base
stage: "Code Quality"
needs: []
script:
- pip install mypy
- mypy src/pystencilssfg
tags:
- docker
- nox --session typecheck
.testsuite-base:
extends: .nox-base
stage: "Tests"
needs: []
coverage: '/TOTAL.*\s+(\d+%)$/'
artifacts:
when: always
paths:
- htmlcov
- coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
"testsuite-py3.10":
extends: .testsuite-base
script:
- nox --session testsuite-3.10
"testsuite-py3.13":
extends: .testsuite-base
script:
- nox --session testsuite-3.13
build-documentation:
stage: test
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
extends: .nox-base
stage: "Documentation"
needs: []
script:
- pip install mkdocs mkdocs-material mkdocstrings[python]
- mkdocs build
tags:
- docker
- nox -s docs -- --fail-on-warnings
artifacts:
paths:
- site
- docs/build/html
when: always
pages:
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
image: alpine:latest
stage: deploy
script:
- ls -l
- mv site public # folder has to be named "public" for gitlab to publish it
- mv docs/build/html public # folder has to be named "public" for gitlab to publish it
artifacts:
paths:
- public
......@@ -51,3 +72,12 @@ pages:
- docker
only:
- master@pycodegen/pystencils-sfg
cmake-standalone:
stage: deploy
needs: []
script:
- echo "Publishing Cmake standalone"
artifacts:
paths:
- standalone
......@@ -13,44 +13,77 @@ As such, any submission of contributions via merge requests is considered as agr
## Developing `pystencils-sfg`
### Prequesites
To develop pystencils-sfg, you will need at least these packages:
- Python 3.10
- Git
- A C++ compiler supporting at least C++20 (gcc >= 10, or clang >= 10)
- GNU Make
- CMake
- Nox
Before continuing, make sure that the above packages are installed on your machine.
### Fork and Clone
To work within the `pystencils-sfg` source tree, first create a *fork* of this repository on GitLab and create
a local clone of your fork.
To work within the `pystencils-sfg` source tree, first create a *fork* of this repository
and clone it to your workstation.
### Set up your dev environment
`pystencils-sfg` uses [`pdm`](https://pdm-project.org) for managing a virtual development environment.
Install `pdm` through your system's package manager and run `pdm sync` in your cloned project directory.
It will set up a virtual environment in the subfolder `.venv`, installing all project dependencies into it.
The `pystencils-sfg` package itself is also installed in editable mode.
You can activate the virtual environment using `eval $(pdm venv activate)`.
Create a virtual environment using either `venv` or `virtualenv` and install the pystencils-sfg source tree
into it using an editable install, e.g. by running the following commands in the `pystencils-sfg` project root directory:
```bash
python -m virtualenv .venv
source .venv/bin/activate
pip install -e .
```
If you have [nox](https://nox.thea.codes/en/stable/) installed, you can also set up your virtual environment
by running `nox --session dev_env`.
### Code Style and Type Checking
To contribute, please adhere to the Python code style set by [PEP 8](https://peps.python.org/pep-0008/).
It is recommended that you use the [black](https://pypi.org/project/black/) formatter to format your source files.
Use flake8 (installed in the `pdm` virtual environment) to check your code style:
For consistency, format all your source files using the [black](https://pypi.org/project/black/) formatter,
and check them regularily using the `flake8` linter through Nox:
```shell
pdm run flake8 src/pystencilssfg
# or, if .venv is activated
flake8 src/pystencilssfg
nox --session lint
```
Further, `pystencils-sfg` takes a rigorous approach to correct static typing.
Further, `pystencils-sfg` is being fully type-checked using [MyPy](https://www.mypy-lang.org/).
All submitted code should contain type annotations ([PEP 484](https://peps.python.org/pep-0484/)) and must be
correctly statically typed.
To check types, we use [MyPy](https://www.mypy-lang.org/), which is automatically installed in the dev environment
and can be invoked as
Regularily check your code for type errors using
```shell
pdm run mypy src/pystencilssfg
# or, if .venv is activated
mypy src/pystencilssfg
nox --session typecheck
```
Both `flake8` and `mypy` are also run in the integration pipeline.
It is furthermore recommended to run both checkers as a git pre-commit hook.
Such a hook can be installed using the [`install_git_hooks.sh`](install_git_hooks.sh) script located at the project root.
### Test Your Code
We are working toward near-complete test coverage of the module source files.
When you add code, make sure to include test cases for both its desired
and exceptional behavior at the appropriate locations in the [tests](tests) directory.
Unit tests should be placed under a path and filename mirroring the location
of the API they are testing within the *pystencils-sfg* source tree.
In [tests/generator_scripts](tests/generator_scripts), a framework is provided to test entire generator scripts
for successful execution, correctness, and compilability of their output.
Read the documentation within [test_generator_scripts.py](tests/generator_scripts/test_generator_scripts.py)
for more information.
Run the test suite by calling it through Nox:
```shell
nox --session testsuite
```
This will also collect coverage information and produce a coverage report as a HTML site placed in the `htmlcov` folder.
# pystencils Source File Generator (pystencils-sfg)
[![](https://img.shields.io/badge/read-the_docs-brightgreen)](https://pycodegen.pages.i10git.cs.fau.de/pystencils-sfg)
[![](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/badges/master/pipeline.svg)](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/commits/master)
[![](https://img.shields.io/gitlab/license/pycodegen%2Fpystencils-sfg?gitlab_url=https%3A%2F%2Fi10git.cs.fau.de)](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/-/blob/master/LICENSE)
[![documentation](https://img.shields.io/badge/read-the_docs-brightgreen)](https://pycodegen.pages.i10git.cs.fau.de/pystencils-sfg)
[![pipeline](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/badges/master/pipeline.svg)](https://i10git.cs.fau.de/pycodegen-/pystencils-sfg/commits/master)
![coverage](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/badges/master/coverage.svg)
[![licence](https://img.shields.io/gitlab/license/pycodegen%2Fpystencils-sfg?gitlab_url=https%3A%2F%2Fi10git.cs.fau.de)](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/-/blob/master/LICENSE)
A bridge over the semantic gap between code emitted by pystencils and your C/C++/Cuda/HIP framework.
......
import pytest
from os import path
DATA_DIR = path.join(path.split(__file__)[0], "tests/data")
@pytest.fixture
def sample_config_module():
return path.join(DATA_DIR, "project_config.py")
@pytest.fixture
def sfg():
from pystencilssfg import SfgContext, SfgComposer
from pystencilssfg.ir import SfgSourceFile, SfgSourceFileType
return SfgComposer(
SfgContext(
header_file=SfgSourceFile("", SfgSourceFileType.HEADER),
impl_file=SfgSourceFile("", SfgSourceFileType.TRANSLATION_UNIT),
)
)
@pytest.fixture(autouse=True)
def prepare_doctest_namespace(doctest_namespace, sfg):
from pystencilssfg import lang
doctest_namespace["sfg"] = sfg
doctest_namespace["lang"] = lang
**/generated
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
::: pystencilssfg.composer.SfgComposer
::: pystencilssfg.composer.SfgBasicComposer
::: pystencilssfg.composer.SfgClassComposer
::: pystencilssfg.composer.make_sequence
\ No newline at end of file
::: pystencilssfg.context.SfgContext
::: pystencilssfg.source_concepts.cpp.std_vector_ref
::: pystencilssfg.source_concepts.cpp.mdspan_ref
::: pystencilssfg.source_concepts.cpp.StdVector
::: pystencilssfg.source_concepts.cpp.StdMdspan
## Output Configuration
::: pystencilssfg.configuration.SfgOutputSpec
## Header-Implementation-Pair Emission
::: pystencilssfg.emission.HeaderImplPairEmitter
## Code Style and `clang-format`
::: pystencilssfg.configuration.SfgCodeStyle
::: pystencilssfg.emission.clang_format.invoke_clang_format
\ No newline at end of file
::: pystencilssfg.generator.SourceFileGenerator
::: pystencilssfg.configuration.SfgConfiguration
::: pystencilssfg.configuration.DEFAULT_CONFIG
# API Documentation
These pages document the public API of *pystencils-sfg*.
### Front End
- [Source File Generator](generator.md)
- [Code Generation Context](context.md)
- [Composer](composer.md)
### Source File Modelling
- [Source File Components](source_components.md)
- [Kernel Call Tree](tree.md)
### High-Level Language Concepts
- [Base Classes](source_objects.md)
- [C++ Standard Library](cpp_std.md)
### Code Generation
- [Emission and Printing](emission.md)
\ No newline at end of file
## Kernels and Kernel Namespaces
::: pystencilssfg.source_components.SfgKernelNamespace
::: pystencilssfg.source_components.SfgKernelHandle
## Includes
::: pystencilssfg.source_components.SfgHeaderInclude
## Functions
::: pystencilssfg.source_components.SfgFunction
## Classes
::: pystencilssfg.source_components.SfgClassKeyword
::: pystencilssfg.source_components.SfgClass
### Visibility
::: pystencilssfg.source_components.SfgVisibility
::: pystencilssfg.source_components.SfgVisibilityBlock
### Members
::: pystencilssfg.source_components.SfgClassMember
::: pystencilssfg.source_components.SfgInClassDefinition
::: pystencilssfg.source_components.SfgConstructor
::: pystencilssfg.source_components.SfgMethod
::: pystencilssfg.source_concepts.SrcObject
::: pystencilssfg.source_concepts.SrcField
::: pystencilssfg.source_concepts.SrcVector
## Base Classes
::: pystencilssfg.tree.SfgCallTreeNode
::: pystencilssfg.tree.SfgCallTreeLeaf
::: pystencilssfg.tree.SfgEmptyNode
## Utility Nodes
::: pystencilssfg.tree.SfgFunctionParams
::: pystencilssfg.tree.SfgRequireIncludes
## Sequences of Statements
::: pystencilssfg.tree.SfgSequence
::: pystencilssfg.tree.SfgStatements
## Structural and Conditional Constructs
::: pystencilssfg.tree.SfgBlock
## Kernel Calls
::: pystencilssfg.tree.SfgKernelCallNode
h2.doc-heading {
font-size: x-large
}
h3.doc-heading {
font-size: large;
}
.doc-class>.doc-heading::before {
font-size: small;
content: "class ";
margin-right: 5pt;
}
.doc-contents {
border-left: 3pt solid rgb(60, 60, 60);
padding-left: 10pt;
}
.doc-class .doc-children .doc-attribute>.doc-heading::before {
font-size: small;
content: "attribute ";
margin-right: 5pt;
}
.doc-class .doc-children .doc-function>.doc-heading::before {
font-size: small;
content: "function ";
margin-right: 5pt;
}
.doc-children {
padding-left: 10pt;
}
\ No newline at end of file
# The pystencils Source File Generator
[![](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/badges/master/pipeline.svg)](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/commits/master)
[![](https://img.shields.io/gitlab/license/pycodegen%2Fpystencils-sfg?gitlab_url=https%3A%2F%2Fi10git.cs.fau.de)](https://i10git.cs.fau.de/pycodegen/pystencils-sfg/-/blob/master/LICENSE)
A bridge over the semantic gap between code emitted by [pystencils](https://pypi.org/project/pystencils/)
and your C/C++/Cuda/HIP framework.
## Installation
### From Git
Install the package into your current Python environment from the git repository using pip
(usage of virtual environments is strongly encouraged!):
```bash
pip install git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git
```
### From PyPI
Not yet available.
## Primer
With *pystencils-sfg*, including your *pystencils*-generated kernels with handwritten code becomes straightforward
and intuitive. To illustrate, generating a Jacobi smoother for the two-dimensional Poisson equation
and mapping it onto C++23 `std::mdspan`s takes just a few lines of code:
```python
import sympy as sp
from pystencils import fields, kernel
from pystencilssfg import SourceFileGenerator, SfgComposer
from pystencilssfg.source_concepts.cpp import mdspan_ref
with SourceFileGenerator() as ctx:
sfg = SfgComposer(ctx)
u_src, u_dst, f = fields("u_src, u_dst, f(1) : double[2D]", layout="fzyx")
h = sp.Symbol("h")
@kernel
def poisson_jacobi():
u_dst[0,0] @= (h**2 * f[0, 0] + u_src[1, 0] + u_src[-1, 0] + u_src[0, 1] + u_src[0, -1]) / 4
poisson_kernel = sfg.kernels.create(poisson_jacobi)
sfg.function("jacobi_smooth")(
sfg.map_field(u_src, mdspan_ref(u_src)),
sfg.map_field(u_dst, mdspan_ref(u_dst)),
sfg.map_field(f, mdspan_ref(f)),
sfg.call(poisson_kernel)
)
```
Take this code, store it into a file `poisson_smoother.py`, and enter the magic words into a terminal:
```shell
python poisson_smoother.py
```
This command will execute the code generator through the `SourceFileGenerator` context manager.
The code generator takes the name of your Python script, replaces `.py` with `.cpp` and `.h`, and writes
`poisson_smoother.cpp` and `poisson_smoother.h` into the current directory, ready to be `#include`d.
The above is what we call a *generator script*; a Python script that, when executed, produces a pair
of source files of the same name, but with different extensions.
Generator scripts are the primary front-end pattern of *pystencils-sfg*; to learn more about them,
read the [Usage Guide](usage/generator_scripts.md).
## CMake Integration
*Pystencils-sfg* comes with a CMake module to register generator scripts for on-the-fly code generation.
With the module loaded, use the function `pystencilssfg_generate_target_sources` inside your `CMakeLists.txt`
to register one or multiple generator scripts; their outputs will automatically be added to the specified target.
```CMake
pystencilssfg_generate_target_sources( <target name>
SCRIPTS kernels.py ...
FILE_EXTENSIONS .h .cpp
)
```
*Pystencils-sfg* makes sure that all generated files are on the project's include path.
To `#include` them, add the prefix `gen/<target name>`:
```C++
#include "gen/<target name>/kernels.h"
```
For details on how to add *pystencils-sfg* to your CMake project, refer to
[CLI and Build System Integration](usage/cli_and_build_system.md).
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd