Skip to content
Snippets Groups Projects
Commit dde18985 authored by Frederik Hennig's avatar Frederik Hennig
Browse files

Write new Getting Started guide. Enable usage of mockup generator for docs.

parent e37859ff
No related branches found
No related tags found
1 merge request!21Composer API Extensions and How-To Guide
Pipeline #73956 passed
**/_sfg_out
\ No newline at end of file
from pystencilssfg import SourceFileGenerator
from pystencilssfg.config import SfgConfig
class DocsMockupGenerator(SourceFileGenerator):
scriptname: str = "script"
def _scriptname(self) -> str:
return f"{DocsMockupGenerator.scriptname}.py"
def __init__(
self, sfg_config: SfgConfig | None = None, keep_unknown_argv: bool = False
):
if sfg_config is None:
sfg_config = SfgConfig()
sfg_config.output_directory = "_sfg_out"
super().__init__(sfg_config, keep_unknown_argv=True)
......@@ -89,17 +89,3 @@ myst_enable_extensions = [
"dollarmath",
"colon_fence",
]
# Prepare code generation examples
def build_examples():
import subprocess
import os
examples_dir = os.path.join("usage", "examples",)
subprocess.run(["python", "build.py"], cwd=examples_dir).check_returncode()
print("Generating output of example scripts...")
build_examples()
---
file_format: mystnb
kernelspec:
name: python3
---
# Getting Started
## Prequesites
To use pystencils-sfg, you will need at least Python 3.10.
You will also need the appropriate compilers for building the generated code,
such as
- a modern C++ compiler (e.g. GCC, clang)
- `nvcc` for CUDA or `hipcc` for HIP
- Intel OneAPI or AdaptiveCpp for SYCL
Furthermore, an installation of clang-format for automatic code formatting is strongly recommended.
## Install the Latest Development Revision
As pystencils-sfg is still unreleased, it can at this time only be obtained directly
from its Git repository.
Create a fresh [virtual environment](https://docs.python.org/3/library/venv.html) or activate
an existing one. Install both the pystencils 2.0 and pystencils-sfg development revisions from Git:
```{code-block} bash
pip install "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev"
pip install "git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git"
```
````{caution}
*pystencils-sfg* is not compatible with the *pystencils 1.3.x* releases available from PyPI;
at the moment, you will still have to manually install the latest version of pystencils 2.0.
````
## Check your Installation
To verify that the SFG was successfully installed, execute the following command:
```{code-block} bash
sfg-cli version
```
You should see an output like `0.1a4+...`.
## Writing a Basic Generator Script
To start using pystencils-sfg, create a new empty Python file and populate it with the
following minimal skeleton:
```{code-block} python
from pystencilssfg import SourceFileGenerator
with SourceFileGenerator() as sfg:
...
```
The above snippet defines the basic structure of a *generator script*.
When executed, the above will produce two (nearly) empty C++ files
in the current folder, both with the same name as your Python script
but with `.hpp` and `.cpp` file extensions instead.
Generator scripts are the primary mode of using pystencils-sfg;
in them, code generation is orchestrated by the `SourceFileGenerator` context manager.
When entering into the region controlled by the `SourceFileGenerator`,
it supplies us with a *composer object*, customarily called `sfg`.
Through the composer, we can declaratively populate the generated files with code.
## Adding a pystencils Kernel
One of the core applications of pystencils-sfg is to generate and wrap pystencils-kernels
for usage within C++ applications.
To register a kernel, pass its assignments to `sfg.kernels.create`.
This gives you a *kernel handle*, through which you can call the kernel from a function:
```{code-cell} ipython3
:tags: [remove-cell]
import sys
from pathlib import Path
mockup_path = Path("_util").resolve()
sys.path.append(str(mockup_path))
from sfg_mockup import DocsMockupGenerator as SourceFileGenerator
```
```{code-cell} ipython3
:tags: [remove-cell]
SourceFileGenerator.scriptname = "demo1"
```
```{code-cell} ipython3
import pystencils as ps
import sympy as sp
with SourceFileGenerator() as sfg:
# Define a copy kernel
src, dst = ps.fields("src, dst: [1D]")
c = sp.Symbol("c")
@ps.kernel
def scale():
dst.center @= c * src.center()
# Register the kernel for code generation
scale_kernel = sfg.kernels.create(scale, "scale_kernel")
# Wrap it in a function
sfg.function("scale")(
sfg.call(scale_kernel)
)
```
::::{tab-set}
:::{tab-item} Generated Header
```{literalinclude} _sfg_out/demo1.hpp
:language: C++
```
:::
:::{tab-item} Generated Implementation
```{literalinclude} _sfg_out/demo1.cpp
:language: C++
```
:::
::::
## Next Steps
# The pystencils Source File Generator
```{toctree}
:maxdepth: 1
:hidden:
getting_started
```
```{toctree}
:maxdepth: 1
:hidden:
......
(guide:generator_scripts)=
# Generator Scripts
# Generator Script Configuration and Command-Line Interface
Writing generator scripts is the primary usage idiom of *pystencils-sfg*.
A generator script is a Python script, say `kernels.py`, which contains *pystencils-sfg*
code at the top level that, when executed, emits source code to a pair of files `kernels.hpp`
and `kernels.cpp`. This guide describes how to write such a generator script, its structure, and how
it can be used to generate code.
Generator scripts are the primary mode of using pystencils-sfg.
A generator script is a Python script, say `kernels.py`, which uses the pystencils-sfg API
at the top level that, when executed, emits source code to a pair of files `kernels.hpp`
and `kernels.cpp`.
This guide describes the basic structure of generator scripts, their execution from the command line,
the configuration of the code generator both inline and from the shell,
as well as customization of their command-line options.
## Anatomy
At minimum, each generator script must contain the following code:
```{code-block} python
from pystencilssfg import SourceFileGenerator
with SourceFileGenerator() as sfg:
...
```
The code generation process begins as the above code enters the region controlled by the
`SourceFileGenerator`.
The object `sfg` in the above snippet is the *composer*, which exposes the primary API
for interacting with the code generator.
The code generation process in a generator script is controlled by the `SourceFileGenerator` context manager.
It configures the code generator by combining configuration options from the
environment (e.g. a CMake build system) with options specified in the script,
......
......@@ -13,8 +13,8 @@ class SfgCodeEmitter:
def __init__(
self,
output_directory: Path,
code_style: CodeStyle,
clang_format: ClangFormatOptions,
code_style: CodeStyle = CodeStyle(),
clang_format: ClangFormatOptions = ClangFormatOptions(),
):
self._output_dir = output_directory
self._code_style = code_style
......
......@@ -32,14 +32,7 @@ class SourceFileGenerator:
`sfg.context.argv`.
"""
def __init__(
self,
sfg_config: SfgConfig | None = None,
keep_unknown_argv: bool = False,
):
if sfg_config and not isinstance(sfg_config, SfgConfig):
raise TypeError("sfg_config is not an SfgConfiguration.")
def _scriptname(self) -> str:
import __main__
if not hasattr(__main__, "__file__"):
......@@ -50,7 +43,17 @@ class SourceFileGenerator:
)
scriptpath = Path(__main__.__file__)
scriptname = scriptpath.name
return scriptpath.name
def __init__(
self,
sfg_config: SfgConfig | None = None,
keep_unknown_argv: bool = False,
):
if sfg_config and not isinstance(sfg_config, SfgConfig):
raise TypeError("sfg_config is not an SfgConfiguration.")
scriptname = self._scriptname()
basename = scriptname.rsplit(".")[0]
from argparse import ArgumentParser
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment