Skip to content
Snippets Groups Projects
Commit c60cce87 authored by Frederik Hennig's avatar Frederik Hennig
Browse files

Begun work on PS-SFG. Kernel namespaces implemented.

parents
No related merge requests found
**/.vscode
**/__pycache__
\ No newline at end of file
# pystencils Source File Generator (ps-sfg)
from .context import SourceFileGenerator, SfgContext
from .kernel_namespace import SfgKernelNamespace, SfgKernelHandle
__all__ = [
'SourceFileGenerator', 'SfgContext',
'SfgKernelNamespace', 'SfgKernelHandle'
]
\ No newline at end of file
from os import path
from .kernel_namespace import SfgKernelNamespace
class SourceFileGenerator:
def __init__(self, namespace: str = "pystencils", basename: str = None):
if basename is None:
import __main__
scriptpath = __main__.__file__
scriptname = path.split(scriptpath)[1]
basename = path.splitext(scriptname)[0]
self.basename = basename
self.header_filename = basename + ".h"
self.cpp_filename = basename + ".cpp"
self._context = SfgContext(namespace)
def __enter__(self):
return self._context
def __exit__(self, *args):
from .emitters.cpu.basic_cpu import BasicCpuEmitter
BasicCpuEmitter(self._context, self.basename).write_files()
class SfgContext:
def __init__(self, root_namespace: str):
self._root_namespace = root_namespace
self._default_kernel_namespace = SfgKernelNamespace(self, "kernels")
self._kernel_namespaces = { self._default_kernel_namespace.name : self._default_kernel_namespace }
@property
def root_namespace(self):
return self._root_namespace
@property
def kernels(self):
return self._default_kernel_namespace
def kernel_namespace(self, name):
if name in self._kernel_namespaces:
raise ValueError(f"Duplicate kernel namespace: {name}")
kns = SfgKernelNamespace(self, name)
self._kernel_namespaces[name] = kns
return kns
@property
def kernel_namespaces(self):
yield from self._kernel_namespaces.values()
from jinja2 import Environment, PackageLoader, StrictUndefined
from ...context import SfgContext
class BasicCpuEmitter:
def __init__(self, ctx: SfgContext, basename: str):
self._ctx = ctx
self._basename = basename
self._header_filename = basename + ".h"
self._cpp_filename = basename + ".cpp"
def write_files(self):
jinja_context = {
'ctx': self._ctx,
'basename': self._basename,
'root_namespace': self._ctx.root_namespace,
'kernel_namespaces': list(self._ctx.kernel_namespaces)
}
template_name = "BasicCpu"
env = Environment(loader=PackageLoader('pystencils_sfg.emitters.cpu'), undefined=StrictUndefined)
from .jinja_filters import add_filters_to_jinja
add_filters_to_jinja(env)
header = env.get_template(f"{template_name}.tmpl.h").render(**jinja_context)
source = env.get_template(f"{template_name}.tmpl.cpp").render(**jinja_context)
with open(self._header_filename, 'w') as headerfile:
headerfile.write(header)
with open(self._cpp_filename, 'w') as cppfile:
cppfile.write(source)
from jinja2 import pass_context
from pystencils.astnodes import KernelFunction
from pystencils import Backend
from pystencils.backends import generate_c
@pass_context
def generate_kernel_definition(ctx, ast: KernelFunction):
return generate_c(ast, dialect=Backend.C)
def add_filters_to_jinja(jinja_env):
jinja_env.filters['generate_kernel_definition'] = generate_kernel_definition
\ No newline at end of file
#include "{{basename}}.h"
#define FUNC_PREFIX inline
namespace {{root_namespace}} {
{% for kns in kernel_namespaces -%}
namespace {{ kns.name }}{
{% for ast in kns.asts -%}
{{ ast | generate_kernel_definition }}
{%- endfor %}
} // namespace {{ kns.name }}
{% endfor %}
} // namespace {{root_namespace}}
#pragma once
#define RESTRICT __restrict__
#include <cstdint>
namespace {{root_namespace}} {
} // namespace {{root_namespace}}
# from .context import SfgContext
from pystencils import CreateKernelConfig, create_kernel
from pystencils.astnodes import KernelFunction
class SfgKernelNamespace:
def __init__(self, ctx, name: str):
self._ctx = ctx
self._name = name
self._asts = dict()
@property
def name(self):
return self._name
@property
def asts(self):
yield from self._asts.values()
def add(self, ast: KernelFunction):
"""Adds an existing pystencils AST to this namespace."""
astname = ast.function_name
if astname in self._asts:
raise ValueError(f"Duplicate ASTs: An AST with name {astname} was already registered in namespace {self._name}")
self._asts[astname] = ast
return SfgKernelHandle(self._ctx, astname, self)
def create(self, assignments, config: CreateKernelConfig):
ast = create_kernel(assignments, config)
return self.add(ast)
class SfgKernelHandle:
def __init__(self, ctx, name: str, namespace: SfgKernelNamespace):
self._ctx = ctx
self._name = name
self._namespace = namespace
@property
def kernel_name(self):
return self._name
@property
def kernel_namespace(self):
return self._namespace
@property
def fully_qualified_name(self):
return f"{self.ctx.root_namespace}::{self.kernel_namespace}::{self.kernel_name}"
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment