diff --git a/docs/Makefile b/docs/Makefile index a293f14ee04261a3d46ac9e6b0924b5b62107a6b..0cfe1ab8baa27928d301317ee7e32a41250d8278 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -22,7 +22,7 @@ html: @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) clean: - rm -rf source/reference/generated rm -rf source/api/generated + rm -rf source/api/symbolic/generated rm -rf source/backend/generated @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/source/api/codegen.rst b/docs/source/api/codegen.rst index d65e9a358296d017e11395050e5767d82d6569ac..1fb83fe5f8bc2d7c22c6893da6ddec8a83c9cb66 100644 --- a/docs/source/api/codegen.rst +++ b/docs/source/api/codegen.rst @@ -1,5 +1,5 @@ -pystencils.codegen -================== +Code Generation +=============== .. module:: pystencils.codegen @@ -15,16 +15,19 @@ Invocation Configuration ------------- +.. module:: pystencils.codegen.config + .. autosummary:: :toctree: generated :nosignatures: - :template: autosummary/entire_class.rst + :template: autosummary/recursive_class.rst CreateKernelConfig - CpuOptimConfig - OpenMpConfig - VectorizationConfig - GpuIndexingConfig + CpuOptions + OpenMpOptions + VectorizationOptions + GpuOptions + SyclOptions .. autosummary:: :toctree: generated @@ -32,9 +35,24 @@ Configuration AUTO +.. dropdown:: Configuration System Implementation Details + + .. autosummary:: + :toctree: generated + :nosignatures: + :template: autosummary/entire_class.rst + + Option + BasicOption + Category + ConfigBase + + Target Specification -------------------- +.. module:: pystencils.codegen.target + .. autosummary:: :toctree: generated :nosignatures: @@ -45,12 +63,14 @@ Target Specification Code Generation Drivers ----------------------- +.. module:: pystencils.codegen.driver + .. autosummary:: :toctree: generated :nosignatures: :template: autosummary/entire_class.rst - driver.DefaultKernelCreationDriver + DefaultKernelCreationDriver .. autosummary:: :toctree: generated @@ -61,6 +81,8 @@ Code Generation Drivers Output Code Objects ------------------- +.. currentmodule:: pystencils.codegen + .. autosummary:: :toctree: generated :nosignatures: diff --git a/docs/source/api/jit.rst b/docs/source/api/jit.rst index 7bcd9989c9f7871eb085e55b7161d1deddda87fc..f2e271db3917825ed7fb6a97c38633a847b8bbfc 100644 --- a/docs/source/api/jit.rst +++ b/docs/source/api/jit.rst @@ -1,5 +1,5 @@ -pystencils.jit -============== +JIT Compilation +=============== .. module:: pystencils.jit diff --git a/docs/source/api/symbolic/assignments.md b/docs/source/api/symbolic/assignments.md new file mode 100644 index 0000000000000000000000000000000000000000..69446a8a551541d555fb7df0d149c2fa2dcf59a6 --- /dev/null +++ b/docs/source/api/symbolic/assignments.md @@ -0,0 +1,16 @@ +# Assignments and AssignmentCollection + +```{eval-rst} + +.. py:class:: pystencils.Assignment + + Monkeypatched variant of `sympy.codegen.ast.Assignment`. + Represents an assignment of an expression to a symbol. + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: autosummary/recursive_class.rst + + pystencils.AssignmentCollection +``` diff --git a/docs/source/api/field.rst b/docs/source/api/symbolic/field.rst similarity index 97% rename from docs/source/api/field.rst rename to docs/source/api/symbolic/field.rst index 79cc12a3a883906a0dd6a2f27d50047344e4c770..33219c059bb3e27160111f5cead50a11ec5736b2 100644 --- a/docs/source/api/field.rst +++ b/docs/source/api/symbolic/field.rst @@ -1,5 +1,5 @@ -pystencils.field -================ +Fields +====== .. module:: pystencils.field diff --git a/docs/source/api/symbolic/index.md b/docs/source/api/symbolic/index.md new file mode 100644 index 0000000000000000000000000000000000000000..fad3df20b68fcac0aba0fcec3ef4564138df5f01 --- /dev/null +++ b/docs/source/api/symbolic/index.md @@ -0,0 +1,9 @@ +# Symbolic Toolbox + +:::{toctree} +:maxdepth: 1 + +field +assignments +sympyextensions +::: diff --git a/docs/source/api/sympyextensions.rst b/docs/source/api/symbolic/sympyextensions.rst similarity index 97% rename from docs/source/api/sympyextensions.rst rename to docs/source/api/symbolic/sympyextensions.rst index d377f998ea5d52189007b7c45f6de2f0d92e1258..e3d10fbdf67a1fc26fe1e339b0e642d86f1be51e 100644 --- a/docs/source/api/sympyextensions.rst +++ b/docs/source/api/symbolic/sympyextensions.rst @@ -1,5 +1,5 @@ -pystencils.sympyextensions -========================== +Extensions to SymPy +=================== .. module:: pystencils.sympyextensions diff --git a/docs/source/reference/types.rst b/docs/source/api/types.rst similarity index 100% rename from docs/source/reference/types.rst rename to docs/source/api/types.rst diff --git a/docs/source/contributing/index.md b/docs/source/contributing/index.md index 39e68b06f4304224fc37e60c8d7611f03ce12d17..04ad821ce5eacdc2f8712ca1f666652b078b7c0f 100644 --- a/docs/source/contributing/index.md +++ b/docs/source/contributing/index.md @@ -1,4 +1,4 @@ -# Contributor Guide +# Contribution Guide Welcome to the Contributor's Guide to pystencils! If you are interested in contributing to the development of pystencils, this is the place to start. diff --git a/docs/source/index.rst b/docs/source/index.rst index 5ddec09f2bb89619cfbc2b6c05c8dcc2bb3108a4..cb455c8b4d1589353a7538c0e98b5eab864b4392 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -77,19 +77,18 @@ Topics .. toctree:: :maxdepth: 1 - :caption: Reference Guides + :caption: User Manual - reference/symbolic_language - reference/kernelcreation - reference/gpu_kernels - reference/types + user_manual/symbolic_language + user_manual/kernelcreation + user_manual/gpu_kernels .. toctree:: :maxdepth: 1 - :caption: API + :caption: API Reference - api/field - api/sympyextensions + api/symbolic/index + api/types api/codegen api/jit diff --git a/docs/source/migration.rst b/docs/source/migration.md similarity index 54% rename from docs/source/migration.rst rename to docs/source/migration.md index ea59d8881a66f992ee2ab99f166deea9e4f70c39..c3cb17d0ffb4ff56ce0480529f78255a41484717 100644 --- a/docs/source/migration.rst +++ b/docs/source/migration.md @@ -1,36 +1,62 @@ -.. _page_v2_migration: +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +mystnb: + execution_mode: cache +--- -*************************** -Version 2.0 Migration Guide -*************************** +(_page_v2_migration)= +# Version 2.0 Migration Guide With version 2.0, many APIs of *pystencils* will be changed; old interfaces are being deprecated and new systems are put in place. This page is a still-incomplete list of these changes, with advice on how to migrate your code from pystencils 1.x to pystencils 2.0. -Kernel Creation -=============== +```{code-cell} ipython3 +:tags: [remove-cell] -Configuration -------------- +import pystencils as ps +``` -The API of `create_kernel`, and the configuration options of the `CreateKernelConfig`, have changed significantly: + +## Kernel Creation + +### Configuration + +The API of {any}`create_kernel`, and the configuration options of the {any}`CreateKernelConfig`, have changed significantly. +The `CreateKernelConfig` class has been refined to be safe to copy and edit incrementally. +The recommended way of setting up the code generator is now *incremental configuration*: + +```{code-cell} ipython3 +cfg = ps.CreateKernelConfig() +cfg.default_dtype = "float32" +cfg.cpu.openmp.enable = True +cfg.cpu.openmp.num_threads = 8 +cfg.ghost_layers = 2 +``` - *Data Types:* `CreateKernelConfig` now takes to parameters to control data types in your kernels: the ``default_dtype`` is applied to all numerical computations, while the ``index_dtype`` is used for all index calculations and loop counters. +- *CPU Optimization Options:* Should now be set via the {any}`cpu <CpuOptions>` option category and its subcategories. .. dropdown:: Deprecated options of `CreateKernelConfig` - ``data_type``: Use ``default_dtype`` instead - - ``cpu_openmp``: Set OpenMP-Options via an `OpenMpConfig` in the ``cpu_optim`` (`CpuOptimConfig`) instead. - - ``cpu_vectorize_info``: Set vectorization options via a `VectorizationConfig` in the ``cpu_optim`` option instead - - ``gpu_indexing_params``: Set GPU indexing options via a `GpuIndexingConfig` in the ``gpu_indexing`` option instead + - ``cpu_openmp``: Set OpenMP-Options in the `cpu.openmp <OpenMpOptions>` category instead. + - ``cpu_vectorize_info``: Set vectorization options in the `cpu.vectorize <VectorizationOptions>` category instead + - ``gpu_indexing_params``: Set GPU indexing options in the `gpu <GpuOptions>` category instead -Type Checking -------------- +### Type Checking The old type checking system of pystencils' code generator has been replaced by a new type inference and validation mechanism whose rules are much stricter than before. @@ -38,24 +64,23 @@ While running `create_kernel`, you may now encounter a `TypificationError` where If this happens, it is probable that you have been doing some illegal, maybe dangerous, or at least unsafe things with data types (like inserting integers into a floating-point context without casting them, or mixing types of different precisions or signedness). If you are sure the error is not your fault, please file an issue at our -`bug tracker <https://i10git.cs.fau.de/pycodegen/pystencils/-/issues>`_. +[bug tracker](https://i10git.cs.fau.de/pycodegen/pystencils/-/issues). -Type System -=========== +### Type System -The ``pystencils.typing`` module has been entirely replaced by the new `pystencils.types` module, +The ``pystencils.typing`` module has been entirely replaced by the new {any}`pystencils.types` module, which is home to a completely new type system. -The primary interaction points with this system are still the `TypedSymbol` class and the `create_type` routine. +The primary interaction points with this system are still the {any}`TypedSymbol` class and the {any}`create_type` routine. Code using any of these two should not require any changes, except: - *Importing `TypedSymbol` and `create_type`:* Both `TypedSymbol` and `create_type` should now be imported directly from the ``pystencils`` namespace. - *Custom data types:* `TypedSymbol` used to accept arbitrary strings as data types. - This is no longer possible; instead, import `pystencils.types.PsCustomType` and use it to describe + This is no longer possible; instead, import {any}`pystencils.types.PsCustomType` and use it to describe custom data types unknown to pystencils, as in ``TypedSymbol("xs", PsCustomType("std::vector< int >"))`` All old data type classes (such as ``BasicType``, ``PointerType``, ``StructType``, etc.) have been removed -and replaced by the class hierarchy below `PsType`. +and replaced by the class hierarchy below {any}`PsType`. Directly using any of these type classes in the frontend is discouraged unless absolutely necessary; in most cases, `create_type` suffices. diff --git a/docs/source/reference/gpu_kernels.md b/docs/source/user_manual/gpu_kernels.md similarity index 97% rename from docs/source/reference/gpu_kernels.md rename to docs/source/user_manual/gpu_kernels.md index 786840d182b0e06d4e26085cf6a95dbcb31d16b2..4db2d79443bc1d09031b3f1a8c8af014a0c824a8 100644 --- a/docs/source/reference/gpu_kernels.md +++ b/docs/source/user_manual/gpu_kernels.md @@ -159,15 +159,10 @@ kernel = ps.create_kernel(assignments, cfg).compile() ``` This warns us that the threads range could not be determined automatically. -We can disable this warning by setting `manual_launch_grid` in the GPU indexing options: +We can disable this warning by setting `manual_launch_grid` in the GPU option category: ```{code-cell} -cfg = ps.CreateKernelConfig( - # ... other options ... - gpu_indexing=ps.GpuIndexingConfig( - manual_launch_grid=True - ) -) +cfg.gpu.manual_launch_grid = True ``` Now, to execute our kernel, we have to manually specify its launch grid: diff --git a/docs/source/reference/kernelcreation.md b/docs/source/user_manual/kernelcreation.md similarity index 99% rename from docs/source/reference/kernelcreation.md rename to docs/source/user_manual/kernelcreation.md index 248855fc1c755d9fee4c62c7db07d469d3ac84ed..c85c8f99d3490602321c57f881b32b0127051c70 100644 --- a/docs/source/reference/kernelcreation.md +++ b/docs/source/user_manual/kernelcreation.md @@ -485,13 +485,10 @@ h = sp.Symbol("h") cfg = ps.CreateKernelConfig( target=ps.Target.X86_AVX512, default_dtype="float32", - cpu_optim=ps.CpuOptimConfig( - openmp=True, - vectorize=ps.VectorizationConfig( - assume_inner_stride_one=True - ) - ) ) +cfg.cpu.openmp.enable = True +cfg.cpu.vectorize.enable = True +cfg.cpu.vectorize.assume_inner_stride_one = True assignments = [ ps.Assignment( diff --git a/docs/source/reference/symbolic_language.rst b/docs/source/user_manual/symbolic_language.rst similarity index 96% rename from docs/source/reference/symbolic_language.rst rename to docs/source/user_manual/symbolic_language.rst index 63b94e04d5026d8210c37db9f2d43f36159aa846..6d219306ec2f677f87f7dd7ca1edb1bd38f3d6d0 100644 --- a/docs/source/reference/symbolic_language.rst +++ b/docs/source/user_manual/symbolic_language.rst @@ -42,10 +42,6 @@ Assignments are the fundamental components of pystencils kernels; they are used both for assigning expressions to symbols and for writing values to fields. -.. py:class:: pystencils.Assignment - - Slightly monkey-patched version of `sympy.codegen.ast.Assignment`. - Assignments are combined and structured inside `assignment collections <pystencils.AssignmentCollection>`. An assignment collection contains two separate lists of assignments: @@ -56,10 +52,9 @@ An assignment collection contains two separate lists of assignments: into fields. .. autosummary:: - :toctree: generated :nosignatures: - :template: autosummary/recursive_class.rst + pystencils.Assignment pystencils.AssignmentCollection diff --git a/src/pystencils/__init__.py b/src/pystencils/__init__.py index 8c59f784624709a380eae4b1a29f36a7ca58d7fd..a23ce185d1a4f6c9cd9a17fccf315462eddf287f 100644 --- a/src/pystencils/__init__.py +++ b/src/pystencils/__init__.py @@ -3,10 +3,6 @@ from .codegen import ( Target, CreateKernelConfig, - CpuOptions, - VectorizationOptions, - OpenMpOptions, - GpuOptions, AUTO ) from .defaults import DEFAULTS @@ -50,10 +46,6 @@ __all__ = [ "create_numeric_type", "make_slice", "CreateKernelConfig", - "CpuOptions", - "VectorizationOptions", - "GpuOptions", - "OpenMpOptions", "AUTO", "create_kernel", "create_staggered_kernel", diff --git a/src/pystencils/backend/transformations/add_pragmas.py b/src/pystencils/backend/transformations/add_pragmas.py index f44b89c723e454f0b221993bbb194505823bc04f..0e6d314acf16a5c16b6cb988f61dfaf4ba8e36f8 100644 --- a/src/pystencils/backend/transformations/add_pragmas.py +++ b/src/pystencils/backend/transformations/add_pragmas.py @@ -98,8 +98,7 @@ class InsertPragmasAtLoops: class AddOpenMP: """Apply OpenMP directives to loop nests. - This transformation augments the AST with OpenMP pragmas according to the given - `OpenMpConfig` configuration. + This transformation augments the AST with OpenMP pragmas according to the given configuration. """ def __init__( diff --git a/src/pystencils/codegen/__init__.py b/src/pystencils/codegen/__init__.py index 3780527c6c0b5bea64a5d0dd2a1800e5a72eb7a3..e13f911dd9c2f8dd1a7b264a79dcdcd51cbef003 100644 --- a/src/pystencils/codegen/__init__.py +++ b/src/pystencils/codegen/__init__.py @@ -1,10 +1,6 @@ from .target import Target from .config import ( CreateKernelConfig, - CpuOptions, - VectorizationOptions, - OpenMpOptions, - GpuOptions, AUTO, ) from .parameters import Parameter @@ -14,10 +10,6 @@ from .driver import create_kernel, get_driver __all__ = [ "Target", "CreateKernelConfig", - "CpuOptions", - "VectorizationOptions", - "OpenMpOptions", - "GpuOptions", "AUTO", "Parameter", "Kernel", diff --git a/src/pystencils/codegen/config.py b/src/pystencils/codegen/config.py index 9abf51222ce99bf9a8cd1472e5afaab3818a13bb..cb457f67396a78fbf4c18305777053597ab4b46f 100644 --- a/src/pystencils/codegen/config.py +++ b/src/pystencils/codegen/config.py @@ -25,7 +25,11 @@ if TYPE_CHECKING: Option_T = TypeVar("Option_T") +"""Type variable for option values""" + + Arg_T = TypeVar("Arg_T") +"""Type variable for option arguments""" class Option(Generic[Option_T, Arg_T]): @@ -35,19 +39,19 @@ class Option(Generic[Option_T, Arg_T]): It maintains a default value for the option that is used when no value was specified by the user. - In configuration options, the value `None` stands for `unset`. + In configuration options, the value `None` stands for ``unset``. It can therefore not be used to set an option to the meaning "not any", or "empty" - for these, special values need to be used. The Option allows a validator function to be specified, which will be called to perform sanity checks on user-provided values. - Through the validator, options may also be set from arguments of a different type (`Arg_T`) - than their value type (`Option_T`). If `Arg_T` is different from `Option_T`, + Through the validator, options may also be set from arguments of a different type (``Arg_T``) + than their value type (``Option_T``). If ``Arg_T`` is different from ``Option_T``, the validator must perform the conversion from the former to the latter. .. note:: - `Arg_T` must always be a supertype of `Option_T`. + ``Arg_T`` must always be a supertype of ``Option_T``. """ def __init__( @@ -99,7 +103,8 @@ class Option(Generic[Option_T, Arg_T]): delattr(obj, self._lookup) -class BasicOption(Option[Option_T, Option_T]): ... # noqa: E701 +class BasicOption(Option[Option_T, Option_T]): + "Subclass of Option where ``Arg_T == Option_T``." class ConfigBase(ABC): @@ -171,6 +176,7 @@ class ConfigBase(ABC): Category_T = TypeVar("Category_T", bound=ConfigBase) +"""Type variable for option categories.""" class Category(Generic[Category_T]): @@ -212,7 +218,7 @@ Currently, these options permit `AUTO`: @dataclass class OpenMpOptions(ConfigBase): - """Parameters controlling kernel parallelization using OpenMP.""" + """Configuration options controlling automatic OpenMP instrumentation.""" enable: BasicOption[bool] = BasicOption(False) """Enable OpenMP instrumentation""" @@ -238,11 +244,7 @@ class OpenMpOptions(ConfigBase): @dataclass class VectorizationOptions(ConfigBase): - """Configuration for the auto-vectorizer. - - If any flag in this configuration is set to a value not supported by the CPU specified - in `CreateKernelConfig.target`, an error will be raised. - """ + """Configuration for the auto-vectorizer.""" enable: BasicOption[bool] = BasicOption(False) """Enable intrinsic vectorization.""" @@ -305,11 +307,7 @@ class VectorizationOptions(ConfigBase): @dataclass class CpuOptions(ConfigBase): - """Configuration for the CPU optimizer. - - If any flag in this configuration is set to a value not supported by the CPU specified - in `CreateKernelConfig.target`, an error will be raised. - """ + """Configuration options specific to CPU targets.""" openmp: Category[OpenMpOptions] = Category(OpenMpOptions()) """Options governing OpenMP-instrumentation. @@ -335,7 +333,7 @@ class CpuOptions(ConfigBase): @dataclass class GpuOptions(ConfigBase): - """Configure index translation behaviour for kernels generated for GPU targets.""" + """Configuration options specific to GPU targets.""" omit_range_check: BasicOption[bool] = BasicOption(False) """If set to `True`, omit the iteration counter range check. @@ -467,13 +465,13 @@ class CreateKernelConfig(ConfigBase): """Target-Specific Options""" cpu: Category[CpuOptions] = Category(CpuOptions()) - """Options for CPU kernels.""" + """Options for CPU kernels. See `CpuOptions`.""" gpu: Category[GpuOptions] = Category(GpuOptions()) - """Options for GPU Kernels.""" + """Options for GPU Kernels. See `GpuOptions`.""" sycl: Category[SyclOptions] = Category(SyclOptions()) - """Options for SYCL kernels.""" + """Options for SYCL kernels. See `SyclOptions`.""" @index_dtype.validate def validate_index_type(self, spec: UserTypeSpec): @@ -503,13 +501,13 @@ class CreateKernelConfig(ConfigBase): """Deprecated; use `default_dtype` instead""" cpu_openmp: InitVar[bool | int | None] = None - """Deprecated; use `cpu_optim.openmp <CpuOptimConfig.openmp>` instead.""" + """Deprecated; use `cpu.openmp <CpuOptions.openmp>` instead.""" cpu_vectorize_info: InitVar[dict | None] = None - """Deprecated; use `cpu_optim.vectorize <CpuOptimConfig.vectorize>` instead.""" + """Deprecated; use `cpu.vectorize <CpuOptions.vectorize>` instead.""" gpu_indexing_params: InitVar[dict | None] = None - """Deprecated; use `gpu_indexing` instead.""" + """Deprecated; set options in the `gpu` category instead.""" # Getters