diff --git a/docs/source/_templates/autosummary/sympy_class.rst b/docs/source/_templates/autosummary/sympy_class.rst new file mode 100644 index 0000000000000000000000000000000000000000..d4fd5208b66817944b75d7f45a463732b4678be2 --- /dev/null +++ b/docs/source/_templates/autosummary/sympy_class.rst @@ -0,0 +1,5 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} diff --git a/docs/source/reference/field.rst b/docs/source/reference/field.rst new file mode 100644 index 0000000000000000000000000000000000000000..7ad7dafee97d86c1ee0b0da1883800b40f844a7f --- /dev/null +++ b/docs/source/reference/field.rst @@ -0,0 +1,74 @@ +pystencils.field +================ + +.. module:: pystencils.field + +.. autoclass:: pystencils.Field + +Types of Fields +--------------- + +.. autoclass:: pystencils.FieldType + +Creating Fields +--------------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + fields + Field.create_generic + Field.create_fixed_size + Field.create_from_numpy_array + Field.new_field_with_different_name + +Properties +---------- + +Name and Element Type +^^^^^^^^^^^^^^^^^^^^^ + +.. autosummary:: + :toctree: autoapi + + Field.name + Field.dtype + Field.itemsize + +Dimensionality, Shape, and Memory Layout +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. autosummary:: + :toctree: autoapi + + Field.ndim + Field.values_per_cell + Field.spatial_dimensions + Field.index_dimensions + Field.spatial_shape + Field.has_fixed_shape + Field.index_shape + Field.has_fixed_index_shape + Field.layout + Field.spatial_strides + Field.index_strides + +Accessing Field Entries +----------------------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + Field.center + Field.center_vector + Field.neighbor + Field.neighbor_vector + Field.__getitem__ + Field.__call__ + Field.absolute_access + Field.staggered_access + Field.staggered_vector_access + +.. autoclass:: pystencils.field.Field.Access diff --git a/docs/source/reference/symbolic_language.rst b/docs/source/reference/symbolic_language.rst index 564eadb6cb788c7c20d503e93766b951411a1456..f56b8e372a3aa888e42cc9661c9dcce09a21c019 100644 --- a/docs/source/reference/symbolic_language.rst +++ b/docs/source/reference/symbolic_language.rst @@ -4,6 +4,14 @@ Symbolic Language ***************** +.. toctree:: + :maxdepth: 2 + :hidden: + + field + sympyextensions + + Pystencils allows you to define near-arbitrarily complex numerical kernels in its symbolic language, which is based on the computer algebra system `SymPy <https://www.sympy.org>`_. The pystencils code generator is able to parse and translate a large portion of SymPy's @@ -23,28 +31,17 @@ The most important extension to SymPy brought by pystencils are *fields*. Fields are a symbolic representation of multidimensional cartesian numerical arrays, as used in many stencil algorithms. They are represented by the `Field` class. -Fields can be created from a textual description using the `fields <pystencils.fields>` function, +Fields can be created from a textual description using the `fields <pystencils.field.fields>` function, or, more concisely, using the factory methods `Field.create_generic` and `Field.create_fixed_size`. It is also possible to create a field representing an existing numpy array, including its shape, data type, and memory layout, using `Field.create_from_numpy_array`. .. autosummary:: - :toctree: autoapi :nosignatures: - :template: autosummary/recursive_class.rst - pystencils.fields pystencils.Field -.. autosummary:: - :nosignatures: - - pystencils.Field.create_generic - pystencils.Field.create_fixed_size - pystencils.Field.create_from_numpy_array - - Assignments and Assignment Collections ====================================== @@ -69,44 +66,11 @@ An assignment collection contains two separate lists of assignments: .. autosummary:: :toctree: autoapi :nosignatures: - :template: recursive_class + :template: autosummary/recursive_class.rst pystencils.AssignmentCollection -Extensions to SymPy -=================== - -Pystencils comes with several extensions to the SymPy symbolic algebra system. - -Expression Rewriting --------------------- - -Typed Expressions ------------------ - -When building numerical kernels with pystencils, it might at some point become -necessary to assert tighter control about the data types of symbols and expressions. -To achieve this, *pystencils* brings a few tools to the table: - -.. autosummary:: - :toctree: autoapi - - pystencils.DynamicType - pystencils.TypedSymbol - pystencils.sympyextensions.CastFunc - - -Integer Operations ------------------- - -.. autosummary:: - :toctree: autoapi - - pystencils.sympyextensions.integer_functions.int_div - pystencils.sympyextensions.integer_functions.int_rem - - Restrictions on SymPy Expressions ================================= diff --git a/docs/source/reference/sympyextensions.rst b/docs/source/reference/sympyextensions.rst new file mode 100644 index 0000000000000000000000000000000000000000..98b6e35938f5362ef9b1c8ac2ad389ac707e692f --- /dev/null +++ b/docs/source/reference/sympyextensions.rst @@ -0,0 +1,94 @@ +pystencils.sympyextensions +========================== + +.. module:: pystencils.sympyextensions + +Symbol Factory +-------------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + SymbolCreator + + +Functions +--------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + math.prod + math.scalar_product + math.kronecker_delta + math.tanh_step_function_approximation + math.multidimensional_sum + + +Expression Analysis +------------------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + math.is_constant + math.summands + math.common_denominator + math.get_symmetric_part + math.count_operations + math.count_operations_in_ast + + +Expression Rewriting and Simplifications +---------------------------------------- + +.. autosummary:: + :toctree: autoapi + :nosignatures: + + math.remove_small_floats + math.is_integer_sequence + math.normalize_product + math.symmetric_product + math.fast_subs + math.subs_additive + math.replace_second_order_products + math.remove_higher_order_terms + math.complete_the_square + math.complete_the_squares_in_exp + math.extract_most_common_factor + math.recursive_collect + math.simplify_by_equality + +Typed Expressions +----------------- + +.. autoclass:: pystencils.TypedSymbol + +.. autoclass:: pystencils.DynamicType + :members: + +.. autoclass:: pystencils.sympyextensions.CastFunc + + +Integer Operations +------------------ + +.. autosummary:: + :toctree: autoapi + :nosignatures: + :template: autosummary/sympy_class.rst + + integer_functions.bitwise_xor + integer_functions.bit_shift_right + integer_functions.bit_shift_left + integer_functions.bitwise_and + integer_functions.bitwise_or + integer_functions.int_div + integer_functions.int_rem + integer_functions.round_to_multiple_towards_zero + integer_functions.ceil_to_multiple + integer_functions.div_ceil diff --git a/src/pystencils/backend/ast/expressions.py b/src/pystencils/backend/ast/expressions.py index a850470ffacf4f528ca5883e5d91b14fa6aa5f9c..e5b3a9df394f2911f02375892e201791c6b6b0ba 100644 --- a/src/pystencils/backend/ast/expressions.py +++ b/src/pystencils/backend/ast/expressions.py @@ -23,7 +23,7 @@ class PsExpression(PsAstNode, ABC): """Base class for all expressions. **Types:** Each expression should be annotated with its type. - Upon construction, the `dtype` property of most expression nodes is unset; + Upon construction, the `dtype <PsExpression.dtype>` property of most expression nodes is unset; only constant expressions, symbol expressions, and array accesses immediately inherit their type from their constant, symbol, or array, respectively. @@ -34,8 +34,8 @@ class PsExpression(PsAstNode, ABC): function materialization and intrinsic selection. .. attention:: - The ``structurally_equal`` check currently does not take expression data types into - account. This may change in the future. + The ``structurally_equal <PsAstNode.structurally_equal>`` check currently does not + take expression data types into account. This may change in the future. """ def __init__(self, dtype: PsType | None = None) -> None: @@ -43,6 +43,7 @@ class PsExpression(PsAstNode, ABC): @property def dtype(self) -> PsType | None: + """Data type assigned to this expression""" return self._dtype @dtype.setter @@ -50,6 +51,11 @@ class PsExpression(PsAstNode, ABC): self._dtype = dt def get_dtype(self) -> PsType: + """Retrieve the data type assigned to this expression. + + Raises: + PsInternalCompilerError: If this expression has no data type assigned + """ if self._dtype is None: raise PsInternalCompilerError("No dtype set on this expression yet.") @@ -111,8 +117,8 @@ class PsExpression(PsAstNode, ABC): Subclasses of `PsExpression` should not override this method, but implement `_clone_expr` instead. That implementation shall call `clone` on any of its subexpressions, - but does not need to fix the `dtype` property. - The `dtype` is correctly applied by `PsExpression.clone` internally. + but does not need to fix the `dtype <PsExpression.dtype>` property. + The ``dtype`` is correctly applied by `PsExpression.clone` internally. """ cloned = self._clone_expr() cloned._dtype = self.dtype diff --git a/src/pystencils/field.py b/src/pystencils/field.py index 1449a51a8a95acef61c9b9dded9dca70084b0319..2eb4b884e3569736f1937610d36f89dc53486285 100644 --- a/src/pystencils/field.py +++ b/src/pystencils/field.py @@ -77,7 +77,7 @@ class Field: This Field class knows about the dimension, memory layout (strides) and optionally about the size of an array. Creating Fields: - The preferred method to create fields is the `fields` function. + The preferred method to create fields is the `fields <pystencils.field.fields>` function. Alternatively one can use one of the static functions `Field.create_generic`, `Field.create_from_numpy_array` and `Field.create_fixed_size`. Don't instantiate the Field directly! Fields can be created with known or unknown shapes: diff --git a/src/pystencils/sympyextensions/math.py b/src/pystencils/sympyextensions/math.py index 6f99be7efd37b3999210824b35300e782ab912c6..9841a98bd83162fbb080db370556de70612bc398 100644 --- a/src/pystencils/sympyextensions/math.py +++ b/src/pystencils/sympyextensions/math.py @@ -674,15 +674,14 @@ def common_denominator(expr: sp.Expr) -> sp.Expr: def get_symmetric_part(expr: sp.Expr, symbols: Iterable[sp.Symbol]) -> sp.Expr: - """ - Returns the symmetric part of a sympy expressions. + """Returns the symmetric part of a sympy expressions. + + This function returns the symmetric part of the given expression w.r.t. the + given degrees of freedom, computed as :math:`\\frac{1}{2} [ f(x_0, x_1, ..) + f(-x_0, -x_1) ]`. Args: expr: sympy expression, labeled here as :math:`f` symbols: sequence of symbols which are considered as degrees of freedom, labeled here as :math:`x_0, x_1,...` - - Returns: - :math:`\frac{1}{2} [ f(x_0, x_1, ..) + f(-x_0, -x_1) ]` """ substitution_dict = {e: -e for e in symbols} return sp.Rational(1, 2) * (expr + expr.subs(substitution_dict)) diff --git a/src/pystencils/sympyextensions/typed_sympy.py b/src/pystencils/sympyextensions/typed_sympy.py index d354dcd6198b878706827dcb6acd9c8ead405ae0..39202296b477dc17ea6e9564548ef841fd04594d 100644 --- a/src/pystencils/sympyextensions/typed_sympy.py +++ b/src/pystencils/sympyextensions/typed_sympy.py @@ -22,8 +22,16 @@ def is_loop_counter_symbol(symbol): class DynamicType(Enum): + """Dynamic data type that will be resolved during kernel creation""" + NUMERIC_TYPE = auto() + """Use the default numeric type set for the kernel""" + INDEX_TYPE = auto() + """Use the default index type set for the kernel. + + This is guaranteed to be an interger type. + """ class TypeAtom(sp.Atom):