From 72f503433f25e6f815f015408f9d9700188890d9 Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Wed, 23 Oct 2024 13:47:59 +0200 Subject: [PATCH] Documentation on buffers --- docs/source/backend/ast.rst | 15 ++++++------ docs/source/backend/index.rst | 1 + docs/source/backend/objects.rst | 39 ++++++++++++++++++++++++++------ docs/source/backend/output.rst | 6 +++++ src/pystencils/backend/memory.py | 22 +++++++++++++++++- 5 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 docs/source/backend/output.rst diff --git a/docs/source/backend/ast.rst b/docs/source/backend/ast.rst index 41f230166..44f8f2540 100644 --- a/docs/source/backend/ast.rst +++ b/docs/source/backend/ast.rst @@ -2,29 +2,30 @@ Abstract Syntax Tree ******************** -Inheritance Diagramm -==================== +API Documentation +================= + +Inheritance Diagram +------------------- .. inheritance-diagram:: pystencils.backend.ast.astnode.PsAstNode pystencils.backend.ast.structural pystencils.backend.ast.expressions pystencils.backend.extensions.foreign_ast :top-classes: pystencils.types.PsAstNode :parts: 1 - Base Classes -============ +------------ .. automodule:: pystencils.backend.ast.astnode :members: Structural Nodes -================ +---------------- .. automodule:: pystencils.backend.ast.structural :members: - Expressions -=========== +----------- .. automodule:: pystencils.backend.ast.expressions :members: diff --git a/docs/source/backend/index.rst b/docs/source/backend/index.rst index b3de9dbf6..70ed684c6 100644 --- a/docs/source/backend/index.rst +++ b/docs/source/backend/index.rst @@ -15,6 +15,7 @@ who wish to customize or extend the behaviour of the code generator in their app translation platforms transformations + output jit extensions diff --git a/docs/source/backend/objects.rst b/docs/source/backend/objects.rst index a39f4c24b..11cf8ea5e 100644 --- a/docs/source/backend/objects.rst +++ b/docs/source/backend/objects.rst @@ -40,18 +40,18 @@ two `PsSymbol` instances with the same name and data type will in general *not* In fact, most of the time, it is an error to have two identical symbol instances active. Creating Symbols ----------------- +^^^^^^^^^^^^^^^^ During kernel translation, symbols never exist in isolation, but should always be managed by a `KernelCreationContext`. -Symbols can be created and retrieved using `KernelCreationContext.add_symbol` and `KernelCreationContext.find_symbol`. -A symbol can also be duplicated using `KernelCreationContext.duplicate_symbol`, which assigns a new name to the symbol's copy. +Symbols can be created and retrieved using `add_symbol <KernelCreationContext.add_symbol>` and `find_symbol <KernelCreationContext.find_symbol>`. +A symbol can also be duplicated using `duplicate_symbol <KernelCreationContext.duplicate_symbol>`, which assigns a new name to the symbol's copy. The `KernelCreationContext` keeps track of all existing symbols during a kernel translation run and makes sure that no name and data type conflicts may arise. Never call the constructor of `PsSymbol` directly unless you really know what you are doing. Symbol Properties ------------------ +^^^^^^^^^^^^^^^^^ Symbols can be annotated with arbitrary information using *symbol properties*. Each symbol property type must be a subclass of `PsSymbolProperty`. @@ -64,6 +64,7 @@ For example, this snippet defines a property type that models pointer alignment @dataclass(frozen=True) class AlignmentProperty(UniqueSymbolProperty) """Require this pointer symbol to be aligned at a particular byte boundary.""" + byte_boundary: int Inheriting from `UniqueSymbolProperty` ensures that at most one property of this type can be attached to @@ -77,10 +78,34 @@ It then becomes the responsibility of the runtime system embedding the kernel to To make sure this information becomes visible, any properties attached to symbols exposed as kernel parameters will also be added to their respective `KernelParameter` instance. -Constants and Literals -====================== - +Buffers +------- +Buffers, as represented by the `PsBuffer` class, represent contiguous, n-dimensional, linearized cuboid blocks of memory. +Each buffer has a fixed name and element data type, +and will be represented in the IR via three sets of symbols: + +- The *base pointer* is a symbol of pointer type which points into the buffer's underlying memory area. + Each buffer has at least one, its primary base pointer, whose pointed-to type must be the same as the + buffer's element type. There may be additional base pointers pointing into subsections of that memory. + These additional base pointers may also have deviating data types, as is for instance required for + type erasure in certain cases. + To communicate its role to the code generation system, + each base pointer needs to be marked as such using the `BufferBasePtr` property, + . +- The buffer *shape* defines the size of the buffer in each dimension. Each shape entry is either a `symbol <PsSymbol>` + or a `constant <PsConstant>`. +- The buffer *strides* define the step size to go from one entry to the next in each dimension. + Like the shape, each stride entry is also either a symbol or a constant. + +The shape and stride symbols must all have the same data type, which will be stored as the buffer's index data type. + +Creating and Managing Buffers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Similarily to symbols, buffers are typically managed by the `KernelCreationContext`, which associates each buffer +to a front-end `Field`. Buffers for fields can be obtained using `get_buffer <KernelCreationContext.get_buffer>`. +The context makes sure to avoid name conflicts between buffers. API Documentation ================= diff --git a/docs/source/backend/output.rst b/docs/source/backend/output.rst new file mode 100644 index 000000000..9875e257b --- /dev/null +++ b/docs/source/backend/output.rst @@ -0,0 +1,6 @@ +********************* +Code Generator Output +********************* + +.. automodule:: pystencils.backend.kernelfunction + :members: diff --git a/src/pystencils/backend/memory.py b/src/pystencils/backend/memory.py index ad28cd3c7..9b72a4e43 100644 --- a/src/pystencils/backend/memory.py +++ b/src/pystencils/backend/memory.py @@ -3,7 +3,7 @@ from typing import Sequence from itertools import chain from dataclasses import dataclass -from ..types import PsType, PsTypeError, deconstify, PsIntegerType +from ..types import PsType, PsTypeError, deconstify, PsIntegerType, PsPointerType from .exceptions import PsInternalCompilerError from .constants import PsConstant from .properties import PsSymbolProperty, UniqueSymbolProperty @@ -119,6 +119,19 @@ class PsBuffer: shape: Sequence[PsSymbol | PsConstant], strides: Sequence[PsSymbol | PsConstant], ): + bptr_type = base_ptr.get_dtype() + + if not isinstance(bptr_type, PsPointerType): + raise ValueError( + f"Type of buffer base pointer {base_ptr} was not a pointer type: {bptr_type}" + ) + + if bptr_type.base_type != element_type: + raise ValueError( + f"Base type of primary buffer base pointer {base_ptr} " + f"did not equal buffer element type {element_type}." + ) + if len(shape) != len(strides): raise ValueError("Buffer shape and stride tuples must have the same length") @@ -148,30 +161,37 @@ class PsBuffer: @property def name(self): + """The buffer's name""" return self._name @property def base_pointer(self) -> PsSymbol: + """Primary base pointer""" return self._base_ptr @property def shape(self) -> tuple[PsSymbol | PsConstant, ...]: + """Buffer shape symbols and/or constants""" return self._shape @property def strides(self) -> tuple[PsSymbol | PsConstant, ...]: + """Buffer stride symbols and/or constants""" return self._strides @property def dim(self) -> int: + """Dimensionality of this buffer""" return len(self._shape) @property def index_type(self) -> PsIntegerType: + """Index data type of this buffer; i.e. data type of its shape and stride symbols""" return self._index_dtype @property def element_type(self) -> PsType: + """Element type of this buffer""" return self._element_type def __repr__(self) -> str: -- GitLab