From b0a9774982a3bb218071f2fb9e4ecd5f658ffa4e Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Wed, 19 Feb 2025 09:48:57 +0100 Subject: [PATCH] Add user guide sections on namespaces and configuration. Clean up various doc comments. --- docs/source/api/composer.rst | 14 +++++++ docs/source/api/generation.rst | 3 ++ docs/source/api/ir.rst | 7 +++- docs/source/getting_started.md | 2 +- docs/source/index.md | 2 +- docs/source/installation.md | 2 +- docs/source/usage/api_modelling.md | 2 +- docs/source/usage/config_and_cli.md | 43 +++++++++++++++++++- docs/source/usage/how_to_composer.md | 35 ++++++++++++++++ src/pystencilssfg/composer/basic_composer.py | 9 ++-- src/pystencilssfg/composer/custom.py | 2 +- src/pystencilssfg/generator.py | 4 +- src/pystencilssfg/ir/postprocessing.py | 2 + 13 files changed, 113 insertions(+), 14 deletions(-) diff --git a/docs/source/api/composer.rst b/docs/source/api/composer.rst index 8d3cdce..124d0fb 100644 --- a/docs/source/api/composer.rst +++ b/docs/source/api/composer.rst @@ -32,6 +32,9 @@ Helper Methods and Builders .. autofunction:: make_sequence +.. autoclass:: KernelsAdder + :members: + .. autoclass:: SfgFunctionSequencer :members: @@ -43,3 +46,14 @@ Helper Methods and Builders .. autoclass:: SfgSwitchBuilder :members: + +Context and Cursor +================== + +.. module:: pystencilssfg.context + +.. autoclass:: SfgContext + :members: + +.. autoclass:: SfgCursor + :members: diff --git a/docs/source/api/generation.rst b/docs/source/api/generation.rst index 935e722..8e7b0b4 100644 --- a/docs/source/api/generation.rst +++ b/docs/source/api/generation.rst @@ -24,6 +24,9 @@ Categories, Parameter Types, and Special Values .. autoclass:: OutputMode :members: +.. autoclass:: FileExtensions + :members: + .. autoclass:: CodeStyle :members: diff --git a/docs/source/api/ir.rst b/docs/source/api/ir.rst index a9451f4..653667b 100644 --- a/docs/source/api/ir.rst +++ b/docs/source/api/ir.rst @@ -1,8 +1,11 @@ Internal Code Representation (`pystencilssfg.ir`) ================================================= -.. autoclass:: pystencilssfg.SfgContext +.. automodule:: pystencilssfg.ir :members: -.. automodule:: pystencilssfg.ir +Postprocessing +-------------- + +.. automodule:: pystencilssfg.ir.postprocessing :members: diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md index 49efbd1..b73a97b 100644 --- a/docs/source/getting_started.md +++ b/docs/source/getting_started.md @@ -4,7 +4,7 @@ kernelspec: name: python3 --- -(getting_started)= +(getting_started_guide)= # Getting Started ```{code-cell} ipython3 diff --git a/docs/source/index.md b/docs/source/index.md index 48df441..c16446d 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -36,7 +36,7 @@ getting_started :caption: User Guide usage/how_to_composer -C++ API Modelling <usage/api_modelling> +usage/api_modelling usage/config_and_cli usage/project_integration usage/tips_n_tricks diff --git a/docs/source/installation.md b/docs/source/installation.md index 77c379b..b60dfb4 100644 --- a/docs/source/installation.md +++ b/docs/source/installation.md @@ -42,4 +42,4 @@ You should see an output like `0.1a4+...`. ## Next Steps -Move on to [](#getting_started) for a guide on how to author simple generator scripts. +Move on to [](#getting_started_guide) for a guide on how to author simple generator scripts. diff --git a/docs/source/usage/api_modelling.md b/docs/source/usage/api_modelling.md index d9a7f04..24591ef 100644 --- a/docs/source/usage/api_modelling.md +++ b/docs/source/usage/api_modelling.md @@ -5,7 +5,7 @@ kernelspec: --- (how_to_cpp_api_modelling)= -# Modelling C++ APIs in pystencils-sfg +# How To Reflect C++ APIs Pystencils-SFG is designed to help you generate C++ code that interfaces with pystencils on the one side, and with your handwritten code on the other side. diff --git a/docs/source/usage/config_and_cli.md b/docs/source/usage/config_and_cli.md index 59f376d..1fdc9df 100644 --- a/docs/source/usage/config_and_cli.md +++ b/docs/source/usage/config_and_cli.md @@ -1,5 +1,5 @@ -(guide:generator_scripts)= +(how_to_generator_scripts_config)= # Generator Script Configuration and Command-Line Interface There are several ways to affect the behavior and output of a generator script. @@ -26,6 +26,47 @@ of the generator script to `gen_src`: ```{literalinclude} examples/guide_generator_scripts/inline_config/kernels.py ``` +For a selection of common configuration options, see [below](#config_options). +The inline configuration will override any values set by the [project configuration](#config_module) +and must not conflict with any [command line arguments](#custom_cli_args). + +(config_options)= +## Configuration Options + +Here is a selection of common configuration options to be set in the [inline configuration](#inline_config) or +[project configuration](#config_module). + +### Output Options + +The file extensions of the generated files can be modified through +{any}`cfg.extensions.header <FileExtensions.header>` +and {any}`cfg.extensions.impl <FileExtensions.impl>`; +and the output directory of the code generator can be set through {any}`cfg.output_directory <SfgConfig.output_directory>`. + +:::{danger} + +When running generator scripts through [CMake](#cmake_integration), you should *never* set the file extensions +and the output directory in the inline configuration. +Both are managed by the pystencils-sfg CMake module, and setting them manually inside the script will +lead to an error. +::: + +### Outer Namespace + +To specify the outer namespace to which all generated code should be emitted, +set {any}`cfg.outer_namespace <SfgConfig.outer_namespace>`. + +### Code Style and Formatting + + - Modify the values in the {any}`cfg.code_style <CodeStyle>` category to affect + certain formatting aspects of the generated code. + - To change, enforce, or disable auto-formatting of generated code through `clang-format`, + take a look at the {any}`cfg.clang_format <ClangFormatOptions>` category. + - Clang-format will, by default, sort `#include` statements alphabetically and separate + local and system header includes. + To override this, you can set a custom sorting key for `#include` sorting via + {any}`cfg.code_style.includes_sorting_key <CodeStyle.includes_sorting_key>`. + (cmdline_options)= ## Command-Line Options diff --git a/docs/source/usage/how_to_composer.md b/docs/source/usage/how_to_composer.md index a2b5984..709d72a 100644 --- a/docs/source/usage/how_to_composer.md +++ b/docs/source/usage/how_to_composer.md @@ -236,6 +236,41 @@ with SourceFileGenerator() as sfg: ) ``` +## Namespaces + +C++ uses namespaces to structure code and group entities. +By default, pystencils-sfg emits all code into the global namespace. +For instructions on how to change the outermost namespace used by the `SourceFileGenerator`, +see [](#how_to_generator_scripts_config). + +Starting from the outermost namespace, nested namespaces can be entered and exited during +code generation. +To enter a new namespace, use `sfg.namespace` in one of two ways: + + - Simply calling `sfg.namespace("my_namespace")` and ignoring its return value will cause the + generator script to use the given namespace for the rest of its execution; + - Calling `sfg.namespace("my_namespace")` in a `with` statement will activate the given namespace + only for the duration of the managed block. + +To illustrate, the following snippet activates the namespace `mylib::generated` for the entire +length of the generator script, and then enters and exits the nested namespace `mylib::generated::detail`: + +```{code-cell} ipython3 +with SourceFileGenerator() as sfg: + sfg.namespace("mylib::generated") + + sfg.code("/* Generated code in outer namespace */") + + with sfg.namespace("detail"): + sfg.code("/* Implementation details in the inner namespace */") + + sfg.code("/* More code in the outer namespace */") +``` + +## Kernels and Kernel Parameter Mappings + + + :::{admonition} To Do - Creating and calling kernels diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index 78f92b8..309ee8b 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -120,7 +120,7 @@ class KernelsAdder: config: CreateKernelConfig | None = None, ): """Creates a new pystencils kernel from a list of assignments and a configuration. - This is a wrapper around `pystencils.create_kernel` + This is a wrapper around `create_kernel <pystencils.codegen.create_kernel>` with a subsequent call to `add`. """ if config is None: @@ -496,7 +496,7 @@ class SfgBasicComposer(SfgIComposer): Args: switch_arg: Argument to the `switch()` statement - autobreak: Whether to automatically print a `break;` at the end of each case block + autobreak: Whether to automatically print a ``break;`` at the end of each case block """ return SfgSwitchBuilder(switch_arg, autobreak=autobreak) @@ -511,7 +511,7 @@ class SfgBasicComposer(SfgIComposer): Args: field: The pystencils field to be mapped - src_object: A `IFieldIndexingProvider` object representing a field data structure. + src_object: An object representing a field data structure. cast_indexing_symbols: Whether to always introduce explicit casts for indexing symbols """ return SfgDeferredFieldMapping( @@ -549,7 +549,8 @@ def make_sequence(*args: SequencerArg) -> SfgSequence: """Construct a sequence of C++ code from various kinds of arguments. `make_sequence` is ubiquitous throughout the function building front-end; - among others, it powers the syntax of `SfgComposer.function` and `SfgComposer.branch`. + among others, it powers the syntax of `SfgBasicComposer.function` + and `SfgBasicComposer.branch`. `make_sequence` constructs an abstract syntax tree for code within a function body, accepting various types of arguments which then get turned into C++ code. These are diff --git a/src/pystencilssfg/composer/custom.py b/src/pystencilssfg/composer/custom.py index 7df364c..10644c6 100644 --- a/src/pystencilssfg/composer/custom.py +++ b/src/pystencilssfg/composer/custom.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: class CustomGenerator(ABC): """Abstract base class for custom code generators that may be passed to - `SfgComposer.generate`.""" + `SfgBasicComposer.generate`.""" @abstractmethod def generate(self, sfg: SfgComposer) -> None: ... diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index ebb84b3..5094403 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -18,8 +18,8 @@ class SourceFileGenerator: """Context manager that controls the code generation process in generator scripts. The `SourceFileGenerator` must be used as a context manager by calling it within - a ``with`` statement in the top-level code of a generator script (see :ref:`guide:generator_scripts`). - Upon entry to its context, it creates an :class:`SfgComposer` which can be used to populate the generated files. + a ``with`` statement in the top-level code of a generator script. + Upon entry to its context, it creates an `SfgComposer` which can be used to populate the generated files. When the managed region finishes, the code files are generated and written to disk at the locations defined by the configuration. Existing copies of the target files are deleted on entry to the managed region, diff --git a/src/pystencilssfg/ir/postprocessing.py b/src/pystencilssfg/ir/postprocessing.py index 5563783..469383c 100644 --- a/src/pystencilssfg/ir/postprocessing.py +++ b/src/pystencilssfg/ir/postprocessing.py @@ -217,6 +217,8 @@ class SfgDeferredParamSetter(SfgDeferredNode): class SfgDeferredFieldMapping(SfgDeferredNode): + """Deferred mapping of a pystencils field to a field data structure.""" + def __init__( self, psfield: Field, -- GitLab