diff --git a/docs/source/backend/ast.rst b/docs/source/backend/ast.rst index 41f23016664002fd100544d72c509f9f73d72bdd..44f8f25409ad08cff1d550dddcd9099bbbc798df 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 b3de9dbf65ce351b82e54d5927ab703088092da3..70ed684c69e494a2c9d72f91fdcc62641f4acd69 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 a39f4c24b1e7b0ceae4f24bdc5b8869b69c080ac..11cf8ea5e53446a0db9dfac18c983e46eaf3bf36 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 0000000000000000000000000000000000000000..9875e257b0ff76de29370dd40a0ab0772ad1fec1 --- /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 ad28cd3c73f2c9f8f7f18865d20ee1bff5222999..9b72a4e4337f1de152291b3287cffb612999a786 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: