diff --git a/pystencilssfg/context.py b/pystencilssfg/context.py index 69ad66c711bf4af7dbec2e5807547daa6bc05a79..61cb60c5876e6c3f9ebb19963d3d44b56ac71dcb 100644 --- a/pystencilssfg/context.py +++ b/pystencilssfg/context.py @@ -57,6 +57,8 @@ class SfgContext: self._config = config self._default_kernel_namespace = SfgKernelNamespace(self, "kernels") + self._code_namespace = None + # Source Components self._includes = set() self._kernel_namespaces = {self._default_kernel_namespace.name: self._default_kernel_namespace} @@ -70,6 +72,18 @@ class SfgContext: def root_namespace(self) -> str: return self._config.base_namespace + @property + def inner_namespace(self) -> str: + return self._code_namespace + + @property + def fully_qualified_namespace(self) -> str: + match (self.root_namespace, self.inner_namespace): + case None, None: return None + case outer, None: return outer + case None, inner: return inner + case outer, inner: return f"{outer}::{inner}" + @property def codestyle(self) -> SfgCodeStyle: return self._config.codestyle diff --git a/pystencilssfg/emitters/cpu/basic_cpu.py b/pystencilssfg/emitters/cpu/basic_cpu.py index 69c718861426c6e7ada997bdca2b380b1defeed9..e6c3438869d40ef69390b8631e3162cd396d798b 100644 --- a/pystencilssfg/emitters/cpu/basic_cpu.py +++ b/pystencilssfg/emitters/cpu/basic_cpu.py @@ -21,12 +21,14 @@ class BasicCpuEmitter: ) def write_files(self, ctx: SfgContext): + fq_namespace = ctx.fully_qualified_namespace + jinja_context = { 'ctx': ctx, 'header_filename': self._header_filename, 'source_filename': self._source_filename, 'basename': self._basename, - 'root_namespace': ctx.root_namespace, + 'fq_namespace': fq_namespace, 'public_includes': list(incl.get_code() for incl in ctx.includes() if not incl.private), 'private_includes': list(incl.get_code() for incl in ctx.includes() if incl.private), 'kernel_namespaces': list(ctx.kernel_namespaces()), @@ -35,7 +37,10 @@ class BasicCpuEmitter: template_name = "BasicCpu" - env = Environment(loader=PackageLoader('pystencilssfg.emitters.cpu'), undefined=StrictUndefined) + env = Environment(loader=PackageLoader('pystencilssfg.emitters.cpu'), + undefined=StrictUndefined, + trim_blocks=True, + lstrip_blocks=True) from .jinja_filters import add_filters_to_jinja add_filters_to_jinja(env) diff --git a/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp b/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp index 1f2e61414e348565b7f14c07f137f3e1fe717955..dfb7a43b0feb1a1a98b8a2237d6c014f7f7f0a67 100644 --- a/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp +++ b/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp @@ -1,18 +1,20 @@ #include "{{header_filename}}" -{% for incl in private_includes -%} +{% for incl in private_includes %} {{incl}} {% endfor %} #define FUNC_PREFIX inline -namespace {{root_namespace}} { +{% if fq_namespace is not none %} +namespace {{fq_namespace}} { +{% endif %} /************************************************************************************* * Kernels *************************************************************************************/ -{% for kns in kernel_namespaces -%} +{% for kns in kernel_namespaces %} namespace {{ kns.name }} { {% for ast in kns.asts %} @@ -32,4 +34,6 @@ void {{ function.name }} ( {{ function | generate_function_parameter_list }} ) { } {% endfor %} -} // namespace {{root_namespace}} +{% if fq_namespace is not none %} +} // namespace {{fq_namespace}} +{% endif %} diff --git a/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h b/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h index cf594e5b53eee8d8a3944a08e4214aa9062d3c26..6cc4e5e8b1152d32e8c388d4d87abba778e45e1c 100644 --- a/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h +++ b/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h @@ -2,16 +2,20 @@ #include <cstdint> -{% for incl in public_includes -%} +{% for incl in public_includes %} {{incl}} {% endfor %} #define RESTRICT __restrict__ -namespace {{root_namespace}} { +{% if fq_namespace is not none %} +namespace {{fq_namespace}} { +{% endif %} {% for function in functions %} void {{ function.name }} ( {{ function | generate_function_parameter_list }} ); {% endfor %} -} // namespace {{root_namespace}} +{% if fq_namespace is not none %} +} // namespace {{fq_namespace}} +{% endif %} \ No newline at end of file diff --git a/pystencilssfg/kernel_namespace.py b/pystencilssfg/kernel_namespace.py index 1204e6cadd9efabf1b7f2c19b7f8afd321f1856b..ce5dde5abfc87e1ecee0afdff397e9e46c51edd2 100644 --- a/pystencilssfg/kernel_namespace.py +++ b/pystencilssfg/kernel_namespace.py @@ -59,7 +59,9 @@ class SfgKernelHandle: @property def fully_qualified_name(self): - return f"{self._ctx.root_namespace}::{self.kernel_namespace.name}::{self.kernel_name}" + match self._ctx.fully_qualified_namespace: + case None: return f"{self.kernel_namespace.name}::{self.kernel_name}" + case fqn: return f"{fqn}::{self.kernel_namespace.name}::{self.kernel_name}" @property def parameters(self): diff --git a/pystencilssfg/tree/basic_nodes.py b/pystencilssfg/tree/basic_nodes.py index 3e0c03c081ceb7298f2a960dd4daf199b5ed3547..89d0edfb22ebe3f0794802943f4dab98e7ab840e 100644 --- a/pystencilssfg/tree/basic_nodes.py +++ b/pystencilssfg/tree/basic_nodes.py @@ -6,7 +6,6 @@ from itertools import chain from ..kernel_namespace import SfgKernelHandle from ..source_concepts.source_objects import SrcObject, TypedSymbolOrObject -from ..exceptions import SfgException if TYPE_CHECKING: from ..context import SfgContext @@ -43,7 +42,6 @@ class SfgCallTreeNode(ABC): By convention, the code block emitted by this function should not contain a trailing newline. """ - pass @property def required_includes(self) -> Set[SfgHeaderInclude]: diff --git a/pystencilssfg/tree/conditional.py b/pystencilssfg/tree/conditional.py index c9c5eaf5f736230af4b2804fd43a9832b1439150..45e91d8f8914c04870c3f97ed3427b3fa892a042 100644 --- a/pystencilssfg/tree/conditional.py +++ b/pystencilssfg/tree/conditional.py @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Sequence, Optional, Set +from typing import TYPE_CHECKING, Optional, Set from .basic_nodes import SfgCallTreeNode, SfgCallTreeLeaf from ..source_concepts.source_objects import TypedSymbolOrObject