From e02732bf96396a2bd85f26d1c2a1c612a1adab7e Mon Sep 17 00:00:00 2001
From: Frederik Hennig <frederik.hennig@fau.de>
Date: Thu, 30 Nov 2023 10:30:03 +0100
Subject: [PATCH] added prelude and definitions

---
 integration/MakeDemo/kernels.py                   |  6 ++++++
 src/pystencilssfg/composer.py                     | 12 +++++++++++-
 src/pystencilssfg/context.py                      |  8 ++++----
 src/pystencilssfg/emitters/cpu/basic_cpu.py       | 15 +++++++++++++++
 .../emitters/cpu/templates/BasicCpu.tmpl.cpp      |  2 ++
 .../emitters/cpu/templates/BasicCpu.tmpl.h        |  6 ++++++
 6 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/integration/MakeDemo/kernels.py b/integration/MakeDemo/kernels.py
index add435f..310b9bc 100644
--- a/integration/MakeDemo/kernels.py
+++ b/integration/MakeDemo/kernels.py
@@ -12,6 +12,12 @@ sfg_config = SfgConfiguration(
 )
 
 with SourceFileGenerator(sfg_config) as sfg:
+    sfg.prelude("""Generated by the pystencils Source File Generator.
+
+Author: Frederik Hennig <frederik.hennig@fau.de>""")
+    
+    sfg.define("using namespace std;")
+    
     sfg.namespace("jacobi")
 
     u_src, u_dst, f = fields("u_src, u_dst, f(1) : double[2D]", layout="fzyx")
diff --git a/src/pystencilssfg/composer.py b/src/pystencilssfg/composer.py
index 8d2c976..d405b66 100644
--- a/src/pystencilssfg/composer.py
+++ b/src/pystencilssfg/composer.py
@@ -24,7 +24,17 @@ class SfgComposer:
     @property
     def context(self):
         return self._ctx
-    
+
+    def prelude(self, content: str):
+        """Add a string to the code file's prelude.
+
+        Do not wrap the given string in comment syntax."""
+        self._ctx.append_to_prelude(content)
+
+    def define(self, definition: str):
+        """Add a custom definition to the generated header file."""
+        self._ctx.add_definition(definition)
+
     def namespace(self, namespace: str):
         """Set the inner code namespace. Throws an exception if a namespace was already set."""
         self._ctx.set_namespace(namespace)
diff --git a/src/pystencilssfg/context.py b/src/pystencilssfg/context.py
index 548d9e5..96649db 100644
--- a/src/pystencilssfg/context.py
+++ b/src/pystencilssfg/context.py
@@ -12,7 +12,7 @@ class SfgContext:
         self._config = config
         self._default_kernel_namespace = SfgKernelNamespace(self, "kernels")
 
-        self._code_namespace = None
+        self._code_namespace: str | None = None
 
         #   Source Components
         self._prelude: list[str] = []
@@ -58,10 +58,10 @@ class SfgContext:
     #   Prelude, Includes, Definitions, Namespace
     # ----------------------------------------------------------------------------------------------
 
-    def prelude_comments(self) -> Generator[str, None, None]:
+    def prelude(self) -> Generator[str, None, None]:
         """The prelude is a comment block printed at the top of both generated files."""
         yield from self._prelude
-    
+
     def append_to_prelude(self, code_str: str):
         self._prelude.append(code_str)
 
@@ -83,7 +83,7 @@ class SfgContext:
     def set_namespace(self, namespace: str):
         if self._code_namespace is not None:
             raise SfgException("The code namespace was already set.")
-        
+
         self._code_namespace = namespace
 
     # ----------------------------------------------------------------------------------------------
diff --git a/src/pystencilssfg/emitters/cpu/basic_cpu.py b/src/pystencilssfg/emitters/cpu/basic_cpu.py
index 46ddfb5..25c952c 100644
--- a/src/pystencilssfg/emitters/cpu/basic_cpu.py
+++ b/src/pystencilssfg/emitters/cpu/basic_cpu.py
@@ -29,6 +29,8 @@ class BasicCpuEmitter:
             'header_filename': self._header_filename,
             'source_filename': self._source_filename,
             'basename': self._basename,
+            'prelude': get_prelude_comment(ctx),
+            'definitions': list(ctx.definitions()),
             '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),
@@ -54,3 +56,16 @@ class BasicCpuEmitter:
 
         with open(path.join(self._output_directory, self._source_filename), 'w') as cppfile:
             cppfile.write(source)
+
+
+def get_prelude_comment(ctx: SfgContext):
+    prelude_lines = []
+    for p in ctx.prelude():
+        prelude_lines += p.splitlines()
+        prelude_lines += [""]   # empty line in-between
+    prelude_lines = prelude_lines[:-1]
+
+    if not prelude_lines:
+        return ""
+
+    return "\n".join(["/**"] + [f"* {line}" for line in prelude_lines] + ["*/"])
diff --git a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp
index 6132d66..12b81bf 100644
--- a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp
+++ b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.cpp
@@ -1,3 +1,5 @@
+{{ prelude }}
+
 #include "{{header_filename}}"
 
 {% for incl in private_includes %}
diff --git a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h
index 6cc4e5e..312e50e 100644
--- a/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h
+++ b/src/pystencilssfg/emitters/cpu/templates/BasicCpu.tmpl.h
@@ -1,3 +1,5 @@
+{{ prelude }}
+
 #pragma once
 
 #include <cstdint>
@@ -6,6 +8,10 @@
 {{incl}}
 {% endfor %}
 
+{% for definition in definitions %}
+{{ definition }}
+{% endfor %}
+
 #define RESTRICT __restrict__
 
 {% if fq_namespace is not none %}
-- 
GitLab