Read about our upcoming Code of Conduct on this issue

Commit 901576f2 authored by Pierre Augier's avatar Pierre Augier
Browse files

Start cachedjit for methods + todolist

parent 6d9d401e2963
......@@ -4,6 +4,8 @@ Future
- :code:`cachedjit` for simple methods (without assignation to attributes
and call of other methods)
- :code:`Union` for annotations
- :code:`include` decorator
0.1.4 (2018-12-06)
------------------
......
......@@ -38,6 +38,8 @@ from .util import (
import_from_path,
has_to_build,
modification_date,
is_method,
path_root,
)
from .pythranizer import (
......@@ -62,6 +64,8 @@ if mpi.nb_proc == 1:
is_transpiling = False
modules = {}
path_cachedjit_classes = mpi.Path(path_root) / "__cachedjit_classes__"
def _get_fluidpythran_calling_module(index_frame: int = 2):
"""Get the FluidPythran instance corresponding to the calling module
......@@ -365,14 +369,7 @@ class FluidPythran:
func: a function
"""
signature = inspect.signature(func)
try:
is_method = next(iter(signature.parameters.keys())) == "self"
except StopIteration:
is_method = False
if is_method:
if is_method(func):
return self.pythran_def_method(func)
if is_transpiling:
......@@ -439,7 +436,12 @@ class FluidPythran:
cls_name = cls.__name__
jit_methods = {}
for key, value in cls.__dict__.items():
if isinstance(value, FluidPythranTemporaryJITMethod):
jit_methods[key] = value
if not isinstance(value, FluidPythranTemporaryMethod):
continue
func = value.func
......@@ -466,7 +468,10 @@ class FluidPythran:
exec(code_new_method, namespace)
setattr(cls, key, functools.wraps(func)(namespace["new_method"]))
return cls
if not jit_methods:
return cls
return cachedjit_class(cls, jit_methods)
def make_signature(self, func, _signature=None, **kwargs):
"""Create signature for a function with values for the template types
......@@ -550,3 +555,49 @@ class FluidPythranTemporaryMethod:
"Did you forget to decorate a class using methods decorated "
"with fluidpythran? Please decorate it with @boost."
)
# FIXME: @include and @include(used_by=("func0", "func1")
class FluidPythranTemporaryJITMethod:
def __init__(self, func, native, xsimd, openmp):
self.func = func
self.native = native
self.xsimd = xsimd
self.openmp = openmp
def __call__(self, self_bis, *args, **kwargs):
raise RuntimeError(
"Did you forget to decorate a class using methods decorated "
"with fluidpythran? Please decorate it with @boost."
)
def cachedjit_class(cls, jit_methods):
"""
1. create a Python file with @cachejit functions and methods
2. import the file
3. replace the methods
"""
# FIXME: to be implemented
cls_name = cls.__name__
mod_name = cls.__module__.__name__
python_path_dir = path_cachedjit_classes / mod_name.replace(".", os.path.sep)
python_path = python_path_dir / (cls_name + ".py")
if has_to_build(python_path, cls.__module__.__file__):
python_code = ...
if python_path.exists():
if mpi.rank == 0:
with open(python_path, "r") as file:
python_code_file = file.read()
# if mpi.rank == 0:
# path_cachedjit_classes.mkdir(parents=True, exist_ok=True)
# mpi.barrier()
raise NotImplementedError
......@@ -247,6 +247,7 @@ class ArrayMeta(type):
return getattr(self, "parameters", tuple())
def get_template_parameters(self):
# FIXME: possible bug "tuple has no value method"
return tuple(
param
for param in self.get_parameters().values()
......@@ -304,6 +305,9 @@ class Array(metaclass=ArrayMeta):
pass
# FIXME: Union
def compute_pythran_types_from_types(types, **kwargs):
"""Compute a list of pythran types
......
......@@ -67,4 +67,4 @@ def check_class():
if __name__ == "__main__":
check_class()
\ No newline at end of file
check_class()
......@@ -78,9 +78,12 @@ from .util import (
has_to_pythranize_at_import,
import_from_path,
pythran,
is_method,
)
from .annotation import make_signatures_from_typehinted_func
from .aheadoftime import FluidPythranTemporaryJITMethod
from .compat import open
from . import mpi
from .log import logger
......@@ -240,6 +243,11 @@ class CachedJIT:
def __call__(self, func):
if is_method(func):
return FluidPythranTemporaryJITMethod(
func, self.native, self.xsimd, self.openmp
)
if not pythran:
return func
......
......@@ -37,7 +37,6 @@ def test_detect_pythran_extensions():
shutil.rmtree(path_data_tests / "__pythran__", ignore_errors=True)
@pytest.mark.skipif(nb_proc > 1, reason="No dist in MPI")
def test_modification_date():
......
......@@ -456,7 +456,7 @@ imports: {imports}\n"""
"module_name not in fluidpythran.aheadoftime.modules\n"
f"module_name = {module_name}"
f"path_py = {path_py}"
)
)
codes_functions = get_code_functions(code, functions)
signatures_func_all = signatures_func
......
......@@ -303,3 +303,13 @@ def clear_cached_extensions(module_name: str, force: bool = False):
for path in (path_pythran, path_ext):
if path.exists():
path.unlink()
def is_method(func):
signature = inspect.signature(func)
try:
answer = next(iter(signature.parameters.keys())) == "self"
except StopIteration:
answer = False
return answer
Markdown is supported
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