From 878467252ec8a932a386190adedec07f77c77c62 Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Tue, 28 Nov 2023 11:57:31 +0100 Subject: [PATCH] Various small changes and additions: - IntEven and IntOdd Conditions - Blank lines in CPU template - Module Exports --- src/pystencilssfg/__init__.py | 3 +- src/pystencilssfg/composer.py | 4 +++ .../emitters/cpu/templates/BasicCpu.tmpl.cpp | 2 ++ src/pystencilssfg/source_components.py | 22 ++++++++++-- src/pystencilssfg/tree/__init__.py | 4 +-- src/pystencilssfg/tree/conditional.py | 34 +++++++++++++++++-- 6 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/pystencilssfg/__init__.py b/src/pystencilssfg/__init__.py index 88a635f..48de907 100644 --- a/src/pystencilssfg/__init__.py +++ b/src/pystencilssfg/__init__.py @@ -1,9 +1,10 @@ from .configuration import SfgConfiguration from .generator import SourceFileGenerator from .composer import SfgComposer +from .context import SfgContext __all__ = [ - "SourceFileGenerator", "SfgComposer", "SfgConfiguration" + "SourceFileGenerator", "SfgComposer", "SfgConfiguration", "SfgContext" ] from . import _version diff --git a/src/pystencilssfg/composer.py b/src/pystencilssfg/composer.py index ce5799f..fa1e8a8 100644 --- a/src/pystencilssfg/composer.py +++ b/src/pystencilssfg/composer.py @@ -21,6 +21,10 @@ class SfgComposer: def __init__(self, ctx: SfgContext): self._ctx = ctx + @property + def context(self): + return self._ctx + @property def kernels(self) -> SfgKernelNamespace: """The default kernel namespace.""" diff --git a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp index dfb7a43..6132d66 100644 --- a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp +++ b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp @@ -29,9 +29,11 @@ namespace {{ kns.name }} { *************************************************************************************/ {% for function in functions %} + void {{ function.name }} ( {{ function | generate_function_parameter_list }} ) { {{ function | generate_function_body | indent(2) }} } + {% endfor %} {% if fq_namespace is not none %} diff --git a/src/pystencilssfg/source_components.py b/src/pystencilssfg/source_components.py index 1c0e104..9c656ca 100644 --- a/src/pystencilssfg/source_components.py +++ b/src/pystencilssfg/source_components.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import TYPE_CHECKING, Sequence +from dataclasses import replace from pystencils import CreateKernelConfig, create_kernel from pystencils.astnodes import KernelFunction @@ -54,17 +55,32 @@ class SfgKernelNamespace: def asts(self): yield from self._asts.values() - def add(self, ast: KernelFunction): + def add(self, ast: KernelFunction, name: str | None = None): """Adds an existing pystencils AST to this namespace.""" - astname = ast.function_name + if name is not None: + astname = name + else: + astname = ast.function_name + if astname in self._asts: raise ValueError(f"Duplicate ASTs: An AST with name {astname} already exists in namespace {self._name}") + if name is not None: + ast.function_name = name + self._asts[astname] = ast return SfgKernelHandle(self._ctx, astname, self, ast.get_parameters()) - def create(self, assignments, config: CreateKernelConfig | None = None): + def create(self, assignments, name: str | None = None, config: CreateKernelConfig | None = None): + if config is None: + config = CreateKernelConfig() + + if name is not None: + if name in self._asts: + raise ValueError(f"Duplicate ASTs: An AST with name {name} already exists in namespace {self._name}") + config = replace(config, function_name=name) + # type: ignore ast = create_kernel(assignments, config=config) return self.add(ast) diff --git a/src/pystencilssfg/tree/__init__.py b/src/pystencilssfg/tree/__init__.py index 8ecc061..f81c917 100644 --- a/src/pystencilssfg/tree/__init__.py +++ b/src/pystencilssfg/tree/__init__.py @@ -1,7 +1,7 @@ from .basic_nodes import SfgCallTreeNode, SfgKernelCallNode, SfgBlock, SfgSequence, SfgStatements -from .conditional import SfgBranch, SfgCondition +from .conditional import SfgBranch, SfgCondition, IntEven, IntOdd __all__ = [ "SfgCallTreeNode", "SfgKernelCallNode", "SfgSequence", "SfgBlock", "SfgStatements", - "SfgCondition", "SfgBranch" + "SfgCondition", "SfgBranch", "IntEven", "IntOdd" ] diff --git a/src/pystencilssfg/tree/conditional.py b/src/pystencilssfg/tree/conditional.py index 39663cb..4c9021a 100644 --- a/src/pystencilssfg/tree/conditional.py +++ b/src/pystencilssfg/tree/conditional.py @@ -1,6 +1,8 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional, cast +from pystencils.typing import TypedSymbol, BasicType + from .basic_nodes import SfgCallTreeNode, SfgCallTreeLeaf from ..source_concepts.source_objects import TypedSymbolOrObject @@ -25,8 +27,36 @@ class SfgCustomCondition(SfgCondition): return self._cond_text -# class IntEven(SfgCondition): -# def __init__(self, ) +class IntEven(SfgCondition): + def __init__(self, symbol: TypedSymbol): + super().__init__() + if not isinstance(symbol.dtype, BasicType) or not symbol.dtype.is_int(): + raise ValueError(f"Symbol {symbol} does not have integer type.") + + self._symbol = symbol + + @property + def required_parameters(self) -> set[TypedSymbolOrObject]: + return {self._symbol} + + def get_code(self, ctx: SfgContext) -> str: + return f"(({self._symbol.name} & 1) ^ 1)" + + +class IntOdd(SfgCondition): + def __init__(self, symbol: TypedSymbol): + super().__init__() + if not isinstance(symbol.dtype, BasicType) or not symbol.dtype.is_int(): + raise ValueError(f"Symbol {symbol} does not have integer type.") + + self._symbol = symbol + + @property + def required_parameters(self) -> set[TypedSymbolOrObject]: + return {self._symbol} + + def get_code(self, ctx: SfgContext) -> str: + return f"({self._symbol.name} & 1)" class SfgBranch(SfgCallTreeNode): -- GitLab