diff --git a/docs/source/backend/index.rst b/docs/source/backend/index.rst index f2fe9346dbe4d38722b69dd9c279d0eb11c98773..b3de9dbf65ce351b82e54d5927ab703088092da3 100644 --- a/docs/source/backend/index.rst +++ b/docs/source/backend/index.rst @@ -30,7 +30,7 @@ The IR comprises *symbols*, *constants*, *arrays*, the *iteration space* and the * `PsSymbol` represents a single symbol in the kernel, annotated with a type. Other than in the frontend, uniqueness of symbols is enforced by the backend: of each symbol, at most one instance may exist. * `PsConstant` provides a type-safe representation of constants. -* `PsLinearizedArray` is the backend counterpart to the ubiquitous `Field`, representing a contiguous +* `PsBuffer` is the backend counterpart to the ubiquitous `Field`, representing a contiguous n-dimensional array. These arrays do not occur directly in the IR, but are represented through their *associated symbols*, which are base pointers, shapes, and strides. diff --git a/docs/source/backend/objects.rst b/docs/source/backend/objects.rst index 1b36842b8d704a4eed9faa1d499be83b0b508106..a28ac3b8534b32d0ef9df946c8980cf97eeaea8c 100644 --- a/docs/source/backend/objects.rst +++ b/docs/source/backend/objects.rst @@ -2,8 +2,8 @@ Constants and Memory Objects **************************** -Memory Objects: Symbols and Field Arrays -======================================== +Memory Objects: Symbols and Buffers +=================================== The Memory Model ---------------- @@ -12,32 +12,91 @@ In order to reason about memory accesses, mutability, invariance, and aliasing, a very simple memory model. There are three types of memory objects: - Symbols (`PsSymbol`), which act as registers for data storage within the scope of a kernel -- Field arrays (`PsLinearizedArray`), which represent a contiguous block of memory the kernel has access to, and +- Field buffers (`PsBuffer`), which represent a contiguous block of memory the kernel has access to, and - the *unmanaged heap*, which is a global catch-all memory object which all pointers not belonging to a field array point into. All of these objects are disjoint, and cannot alias each other. Each symbol exists in isolation, -field arrays do not overlap, +field buffers do not overlap, and raw pointers are assumed not to point into memory owned by a symbol or field array. Instead, all raw pointers point into unmanaged heap memory, and are assumed to *always* alias one another: Each change brought to unmanaged memory by one raw pointer is assumed to affect the memory pointed to by another raw pointer. -Classes +Symbols ------- -.. autoclass:: pystencils.backend.symbols.PsSymbol - :members: +In the pystencils IR, instances of `PsSymbol` represent what is generally known as "virtual registers". +These are memory locations that are private to a function, cannot be aliased or pointed to, and will finally reside +either in physical registers or on the stack. +Each symbol has a name and a data type. The data type may initially be `None`, in which case it should soon after be +determined by the `Typifier`. -.. automodule:: pystencils.backend.arrays - :members: +Other than their front-end counterpart `sympy.Symbol <sympy.core.symbol.Symbol>`, `PsSymbol` instances are mutable; +their properties can and often will change over time. +As a consequence, they are not comparable by value: +two `PsSymbol` instances with the same name and data type will in general *not* be equal. +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. +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`. +It is strongly recommended to implement property types using frozen +`dataclasses <https://docs.python.org/3/library/dataclasses.html>`_. +For example, this snippet defines a property type that models pointer alignment requirements: + +.. code-block:: python + + @dataclass(frozen=True) + class AlignmentProperty(PsSymbolProperty) + """Require this pointer symbol to be aligned at a particular byte boundary.""" + byte_boundary: int + _unique: ClassVar[bool] = True + +The ``_unique`` flag in the above example ensures that only one property of this type can at any time +be attached to a symbol. +Properties can be added, queried, and removed using the `PsSymbol` properties API listed below. + +Many symbol properties are more relevant to consumers of generated kernels than to the code generator itself. +The above alignment property, for instance, may be added to a pointer symbol by a vectorization pass +to document its assumption that the pointer be properly aligned, in order to emit aligned load and store instructions. +It then becomes the responsibility of the runtime system embedding the kernel to check this prequesite before calling the kernel. +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 ====================== -.. autoclass:: pystencils.backend.constants.PsConstant + + +API Documentation +================= + +The `memory <pystencils.backend.memory>` Module +----------------------------------------------- + +.. automodule:: pystencils.backend.memory + :members: + +The `constants <pystencils.backend.constants>` Module +----------------------------------------------------- + +.. automodule:: pystencils.backend.constants :members: .. autoclass:: pystencils.backend.literals.PsLiteral diff --git a/src/pystencils/backend/memory.py b/src/pystencils/backend/memory.py index b0333bd6677ac163a23aaa9418985c9cb8c4fda5..6bc7039f52f63bb43ecd4cf2101e4f19c1950791 100644 --- a/src/pystencils/backend/memory.py +++ b/src/pystencils/backend/memory.py @@ -122,7 +122,7 @@ class PsSymbol: @dataclass(frozen=True) class BufferBasePtr(PsSymbolProperty): - """Symbol acts as a base pointer to a field.""" + """Symbol acts as a base pointer to a buffer.""" buffer: PsBuffer @@ -140,7 +140,7 @@ class PsBuffer: All indexing expressions must have the same data type, which will be selected as the buffer's `index_dtype`. - Each buffer has at least one base pointer, which can be retrieved via the `base_pointer` + Each buffer has at least one base pointer, which can be retrieved via the `PsBuffer.base_pointer` property. """