Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiled backends integration #835

Merged
merged 89 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
6bad5c4
compiled backends code
petiaccja Jun 20, 2022
77c2075
tests for compiled backends
petiaccja Jun 20, 2022
da31c54
rebased to Rico's backend cleanup
petiaccja Jul 4, 2022
217f6b1
merged online compilation into Rico's backend structure
petiaccja Jul 6, 2022
5b01ca2
renamed test folder to match backend's structure
petiaccja Jul 6, 2022
1307bad
set up C++ dev tools and libs
petiaccja Jul 6, 2022
e9740b1
fixed style and quality problems
petiaccja Jul 6, 2022
4bb8b4d
Merge remote-tracking branch 'origin/functional' into compiled-backen…
petiaccja Jul 7, 2022
7863592
fixed problems after merge
petiaccja Jul 7, 2022
2c05f7b
added parametric tests and fixed issues
petiaccja Jul 7, 2022
016b914
parametrized simple tests
petiaccja Jul 7, 2022
3c91964
fixed qa
petiaccja Jul 7, 2022
6c4dc2e
renamed modules -> importer
petiaccja Jul 8, 2022
2c8df46
uses compiled module suffix from importlib; uses specs for importing …
petiaccja Jul 8, 2022
4395143
removed formatting from ir
petiaccja Jul 8, 2022
d97e61a
Merge remote-tracking branch 'origin/functional' into compiled-backen…
petiaccja Jul 11, 2022
5aec53a
use pybind11 from pip
petiaccja Jul 11, 2022
79d06c6
remove pybind11 from ci yaml
petiaccja Jul 11, 2022
1629234
fixed tests and formatting
petiaccja Jul 11, 2022
cf87aa7
simplified parameter creation helpers
petiaccja Jul 11, 2022
3184f80
added a sid expr node and moved stencil argument rendering into code …
petiaccja Jul 11, 2022
d663b65
links to GridTools::fn_naive and removed all explicit references to o…
petiaccja Jul 11, 2022
5a1ace1
require c++17 on target instead of globally
petiaccja Jul 11, 2022
4ec81b3
removed threads library requirement from cmake
petiaccja Jul 11, 2022
aad9b05
fixed cartesian offsets
petiaccja Jul 11, 2022
8b3114c
removed questionable line of test
petiaccja Jul 11, 2022
e4424e9
parametrize fieldview tests and skip unsupported
Jul 11, 2022
93af467
Merge branch 'cbi-plus-tests' into compiled-backends-integration
Jul 11, 2022
aee5887
added license headers for the entire fencil_processors folder
petiaccja Jul 12, 2022
5fc0f98
typo in type annotations
petiaccja Jul 12, 2022
ece2641
using match statement in cache instead of dict
petiaccja Jul 12, 2022
4c19f07
simplify pytest.skip calls, run pre-commit
Jul 13, 2022
e6d0871
adr parts
petiaccja Jul 13, 2022
3c5a8b1
stage
petiaccja Jul 14, 2022
ee0059d
few words about limitations
petiaccja Jul 14, 2022
ccacd74
Update ADR
DropD Jul 14, 2022
827ce57
use ninja and cmake from pip
petiaccja Jul 15, 2022
887020b
extended caching to consider all module parameters
petiaccja Jul 18, 2022
b5fbaea
Update src/functional/fencil_processors/cpp.py
petiaccja Jul 19, 2022
de16028
renamed some things
petiaccja Jul 19, 2022
8a220b8
some missing return types
petiaccja Jul 19, 2022
0a55dea
update ADR based on review comments
Jul 19, 2022
c3f250c
improve ADR
Jul 19, 2022
01c3a93
add docstrings to cbi caching
Jul 19, 2022
ea121d0
cbi: add importer docstring
Jul 19, 2022
05daec4
rename var
petiaccja Jul 19, 2022
6389e7b
some doc comments
petiaccja Jul 19, 2022
3f9a965
fix tempdir
petiaccja Jul 20, 2022
f1367a6
replaced deprecated typing.Callable with collections.abc.Callable
petiaccja Jul 20, 2022
27e0cfa
grammar / typo
petiaccja Jul 20, 2022
494c9e0
naming conventions
petiaccja Jul 20, 2022
bc34df0
enforce keyword arguments for optionals
petiaccja Jul 20, 2022
c2ad1dd
using as_jinja for JinjaTemplate for consistency
petiaccja Jul 20, 2022
3204d7f
cbi: eve.codegen import conventions
Jul 20, 2022
03179ee
Merge remote-tracking branch 'upstream/compiled-backends-integration'…
Jul 20, 2022
0322f84
cbi: bindings docstrings
Jul 20, 2022
48c9baa
cbi: builders.cpp.build docstrings
Jul 20, 2022
0fe9396
cbi: ADR and some todos
Jul 20, 2022
16de03c
cbi: simplify importer
Jul 20, 2022
63c59f0
Update src/functional/fencil_processors/codegens/gtfn/gtfn_module.py
DropD Jul 20, 2022
c9d7d32
avoid making numpy copies
petiaccja Jul 20, 2022
b5d550e
cleaned up cmakeproject
petiaccja Jul 20, 2022
af2792c
redo ugly method to fix stuff but this could indeed be improved
petiaccja Jul 20, 2022
5004ed0
cbi: revert earlier erroneous importer change
Jul 20, 2022
83589e1
Merge remote-tracking branch 'upstream/compiled-backends-integration'…
Jul 20, 2022
20fc3b1
cbi: small formatting change
Jul 20, 2022
8e292d3
more doc
petiaccja Jul 20, 2022
5051334
remove unnecessary functions
petiaccja Jul 20, 2022
95f2f75
further simplification
petiaccja Jul 20, 2022
2115514
changed source modules to use numpy.dtype instead of raw types
petiaccja Jul 20, 2022
a4beee1
bugfix
petiaccja Jul 21, 2022
8d4b9a2
delete init.py from tests
petiaccja Jul 21, 2022
a63070a
simplified code with fstrings
petiaccja Jul 21, 2022
818b1a5
froze dataclasses for source modules
petiaccja Jul 21, 2022
5fa4dff
formatting
petiaccja Jul 21, 2022
8ba269e
simplified binding code gen
petiaccja Jul 21, 2022
50a0111
cleaned up bindings ast
petiaccja Jul 21, 2022
5eb5905
Merge remote-tracking branch 'origin/functional' into compiled-backen…
petiaccja Jul 21, 2022
a896ede
fixed tests
petiaccja Jul 21, 2022
ae9a2a5
minor spelling changes to adr
petiaccja Jul 21, 2022
ca012a3
typo
petiaccja Jul 22, 2022
d85cdd1
typo
petiaccja Jul 22, 2022
b1779e0
minor fixes
petiaccja Jul 22, 2022
505e192
adding CMakeProject design considerations to ADR
Jul 22, 2022
2e3ddc2
cpp->python type mapping global & MappingProxyType
petiaccja Jul 22, 2022
2e43a85
formatting
petiaccja Jul 22, 2022
c46611c
wording
petiaccja Jul 22, 2022
6e05a26
wording & clarification
petiaccja Jul 22, 2022
cc28b32
delete init.py from tests
petiaccja Jul 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
tox-tests:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.10"]
Expand All @@ -34,6 +34,12 @@ jobs:
- name: Install python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
- name: Set up C++ devtools
uses: seanmiddleditch/gha-setup-ninja@v3
petiaccja marked this conversation as resolved.
Show resolved Hide resolved
petiaccja marked this conversation as resolved.
Show resolved Hide resolved
- name: Install C++ dependencies
run: |
sudo apt install pybind11-dev
petiaccja marked this conversation as resolved.
Show resolved Hide resolved
sudo apt install libboost-all-dev
- name: Test with tox
run: |
pyversion_no_dot="${{ matrix.python-version }}"
Expand Down
Empty file.
38 changes: 38 additions & 0 deletions src/functional/fencil_processors/callables/cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import enum
import hashlib
import pathlib
import tempfile


class Strategy(enum.Enum):
SESSION = 1
PERSISTENT = 2


_session_cache_dir = tempfile.TemporaryDirectory(prefix="gt4py_session_")

_session_cache_dir_path = pathlib.Path(_session_cache_dir.name)
_persistent_cache_dir_path = (
pathlib.Path(tempfile.tempdir) / "gt4py_cache" if tempfile.tempdir else _session_cache_dir_path
)


def _cache_folder_name(module_name: str, module_src: str) -> str:
hashed = hashlib.sha256(module_src.encode(encoding="utf-8"))
hashed_str = hashed.hexdigest()
return module_name + "_" + hashed_str


def get_cache_folder(module_name: str, module_src: str, strategy: Strategy) -> pathlib.Path:
folder_name = _cache_folder_name(module_name, module_src)

base_path = {
Strategy.SESSION: _session_cache_dir_path,
Strategy.PERSISTENT: _persistent_cache_dir_path,
}[strategy]
petiaccja marked this conversation as resolved.
Show resolved Hide resolved
base_path.mkdir(exist_ok=True)

complete_path = base_path / folder_name
complete_path.mkdir(exist_ok=True)

return complete_path
4 changes: 4 additions & 0 deletions src/functional/fencil_processors/callables/cpp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .callable import create_callable


__all__ = ["create_callable"]
220 changes: 220 additions & 0 deletions src/functional/fencil_processors/callables/cpp/bindings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import os
import typing
from typing import Any, Sequence, Type, TypeVar

import jinja2

import eve.codegen
import functional.fencil_processors.cpp as cpp
import functional.fencil_processors.defs as defs
from eve import Node
from eve.codegen import JinjaTemplate, TemplatedGenerator


T = TypeVar("T")


class CommaSeparatedList(Node):
items: list


class NewlineSeparatedList(Node):
items: list

petiaccja marked this conversation as resolved.
Show resolved Hide resolved

class BindingFunction(Node):
exported_name: str
wrapper_name: str
doc: str


class BindingModule(Node):
name: str
doc: str
functions: NewlineSeparatedList


class FunctionParameter(Node):
name: str
ndim: int
dtype: Type


class FunctionCall(Node):
target: defs.Function
petiaccja marked this conversation as resolved.
Show resolved Hide resolved


class ReturnStmt(Node):
expr: Any


class GridToolsSidExpr(Node):
name: str
num_dims: int
dtype: typing.Type
dim_config: int


class SidExpr(Node):
identifier: str


class WrapperFunction(Node):
name: str
parameters: CommaSeparatedList
body: Any


class BindingFile(Node):
callee_header_file: str
header_files: list[str]
wrapper: WrapperFunction
binding_module: BindingModule


class BindingCodeGenerator(TemplatedGenerator):
BindingFile = JinjaTemplate(
"""\
#include "{{callee_header_file}}"

{% for header_file in header_files: %}\
#include <{{header_file}}>
{% endfor %}

{{wrapper}}

{{binding_module}}\
"""
)

WrapperFunction = JinjaTemplate(
"""\
decltype(auto) {{name}}(
{{parameters}}
)
{
{{body}}
}\
"""
)

def visit_FunctionParameter(self, param: FunctionParameter):
if param.ndim > 0:
type_str = "pybind11::buffer"
else:
type_str = cpp.render_python_type(param.dtype)
return type_str + " " + param.name

FunctionArgument = JinjaTemplate("""{{expr}}""")

ReturnStmt = JinjaTemplate("""return {{expr}};""")

def visit_GridToolsSidExpr(self, expr: GridToolsSidExpr):
template = jinja2.Template(
"""\
gridtools::as_sid<{{dtype}},\
{{num_dims}},\
gridtools::integral_constant<int, {{dim_config}}>,\
999'999'999>({{name}})\
"""
)
return template.render(
name=expr.name,
num_dims=expr.num_dims,
dtype=cpp.render_python_type(expr.dtype),
dim_config=expr.dim_config,
)

BindingModule = JinjaTemplate(
"""\
PYBIND11_MODULE({{name}}, module) {
module.doc() = "{{doc}}";
{{functions}}
}\
"""
)

BindingFunction = JinjaTemplate(
"""module.def("{{exported_name}}", &{{wrapper_name}}, "{{doc}}");"""
)

def visit_CommaSeparatedList(self, items: NewlineSeparatedList):
str_items = [self.visit(item) for item in items.items]
return ", ".join(str_items)

def visit_NewlineSeparatedList(self, items: NewlineSeparatedList):
str_items = [self.visit(item) for item in items.items]
return str(os.linesep).join(str_items)

def visit_FunctionCall(self, call: FunctionCall):
args = [render_argument(index, param) for index, param in enumerate(call.target.parameters)]
return cpp.render_function_call(call.target, args)


def make_parameter_list(
parameters: Sequence[defs.ScalarParameter | defs.BufferParameter],
) -> Sequence[FunctionParameter]:
def make_parameter(parameter: defs.ScalarParameter | defs.BufferParameter):
petiaccja marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(parameter, defs.ScalarParameter):
return FunctionParameter(name=parameter.name, ndim=0, dtype=parameter.type_)
else:
return FunctionParameter(
name=parameter.name, ndim=parameter.num_dimensions, dtype=parameter.scalar_type
)

regulars = [make_parameter(param) for param in parameters]
return regulars


def render_argument(index: int, param: defs.ScalarParameter | defs.BufferParameter) -> str:
if isinstance(param, defs.ScalarParameter):
return """{name}""".format(name=param.name)
else:
template = jinja2.Template(
"""\
gridtools::as_sid<{{dtype}},\
{{ndims}},\
gridtools::integral_constant<int, {{dim_config}}>,\
999'999'999>({{name}})\
"""
)
return template.render(
name=param.name,
ndims=param.num_dimensions,
dtype=cpp.render_python_type(param.scalar_type),
dim_config=index,
)


def create_bindings(target: defs.Function, target_header: str) -> defs.BindingCodeModule:
wrapper_name = target.name + "_wrapper"

file_binding = BindingFile(
callee_header_file=target_header,
header_files=[
"pybind11/pybind11.h",
"pybind11/stl.h",
"gridtools/storage/adapter/python_sid_adapter.hpp",
"gridtools/common/defs.hpp",
"gridtools/fn/unstructured.hpp",
"gridtools/fn/cartesian.hpp",
"gridtools/fn/backend/naive.hpp",
],
wrapper=WrapperFunction(
name=wrapper_name,
parameters=CommaSeparatedList(items=make_parameter_list(target.parameters)),
body=ReturnStmt(expr=FunctionCall(target=target)),
),
binding_module=BindingModule(
name=target.name,
doc="",
functions=NewlineSeparatedList(
items=[
BindingFunction(exported_name=target.name, wrapper_name=wrapper_name, doc="")
]
),
),
)

src = eve.codegen.format_source("cpp", BindingCodeGenerator.apply(file_binding), style="LLVM")
return defs.BindingCodeModule(src, [defs.LibraryDependency("pybind11", "2.9.2")])
Loading