Read about our upcoming Code of Conduct on this issue

Commit fe65055a authored by Pierre Augier's avatar Pierre Augier
Browse files

__returns__

parent 6ca775f2d956
......@@ -2,13 +2,13 @@
all:
TRANSONIC_BACKEND="pythran" transonic add.py
TRANSONIC_BACKEND="numba" transonic add.py
# TRANSONIC_BACKEND="cython" transonic add.py
TRANSONIC_BACKEND="cython" transonic add.py
bench:
TRANSONIC_NO_REPLACE=1 python add.py
TRANSONIC_BACKEND="pythran" python add.py
TRANSONIC_BACKEND="numba" python add.py
# TRANSONIC_BACKEND="cython" python add.py
TRANSONIC_BACKEND="cython" python add.py
clean:
rm -rf __pythran__ __cython__ __numba__
\ No newline at end of file
......@@ -5,8 +5,7 @@ T = int
@boost(inline=True)
def add(a: T, b: T):
# -> T: # not yet supported
def add(a: T, b: T) -> T:
return a + b
......
import cython
import numpy as np
cimport numpy as np
ctypedef fused __add_a:
cython.int
ctypedef fused __add_b:
cython.int
cdef inline int add(__add_a a, __add_b b)
ctypedef fused __use_add_n:
cython.int
@cython.locals(tmp=cython.int, _=cython.int)
cpdef use_add(__use_add_n n=*)
def add(a, b):
# -> T: # not yet supported
return a + b
def use_add(n=10000):
tmp = 0
for _ in range(n):
tmp = add(tmp, 1)
return tmp
__transonic__ = ("0.3.2",)
import gast as ast
import beniget
mod = ast.parse("""
T = int
def func() -> T:
return 1
""")
fdef = mod.body[1]
node = fdef.returns
du = beniget.DefUseChains()
du.visit(mod)
du.chains[node]
ud = beniget.UseDefChains(du)
ud.chains[node]
\ No newline at end of file
......@@ -30,6 +30,7 @@ from .util import (
find_path,
get_exterior_code,
extract_variable_annotations,
extract_returns_annotation,
)
from .capturex import CaptureX
from .blocks_if import get_block_definitions
......@@ -311,6 +312,7 @@ def analyse_aot(code, pathfile):
annotations["__in_comments__"] = {}
annotations["__locals__"] = {}
annotations["__returns__"] = {}
for functions_backend in boosted_dicts["functions"].values():
for name_func, fdef in functions_backend.items():
......@@ -334,6 +336,11 @@ def analyse_aot(code, pathfile):
if annotations_locals:
annotations["__locals__"][name_func] = annotations_locals
if fdef.returns:
annotations["__returns__"][
name_func
] = extract_returns_annotation(fdef.returns, namespace)
debug("annotations:\n" + pformat(annotations))
return boosted_dicts, code_dependance, annotations, blocks, code_ext
......@@ -57,6 +57,13 @@ class CaptureX(ast.NodeVisitor):
def visit_Name(self, node):
# register load of identifiers not locally defined
if isinstance(node.ctx, ast.Load):
try:
self.ud_chains.chains[node]
except KeyError:
from transonic.analyses import print_dumped
print(f"BUG Beniget? (node.id={node.id}) Still we continue!")
return
for def_ in self.ud_chains.chains[node]:
try:
parents = self.ancestors.parents(def_.node)
......
......@@ -423,3 +423,10 @@ def extract_variable_annotations(fdef, namespace):
variable_types[name] = result
return variable_types
def extract_returns_annotation(returns, namespace):
if returns is None:
return
source = extast.unparse(returns)
return eval(source, namespace)
......@@ -175,12 +175,9 @@ class Backend:
boosted_dicts, code_dependance, annotations, blocks, codes_ext = analyse
boosted_dicts = dict(
functions=boosted_dicts["functions"][self.name],
functions_ext=boosted_dicts["functions_ext"][self.name],
methods=boosted_dicts["methods"][self.name],
classes=boosted_dicts["classes"][self.name],
)
boosted_dicts = {
key: value[self.name] for key, value in boosted_dicts.items()
}
lines_code = ["\n" + code_dependance + "\n"]
lines_header = self._make_first_lines_header()
......@@ -355,7 +352,12 @@ class Backend:
raise NotImplementedError
def _make_header_from_fdef_signatures(
self, fdef, signatures_as_lists_strings, locals_types=None
self,
fdef,
signatures_as_lists_strings,
locals_types=None,
returns=None,
inline=False,
):
raise NotImplementedError
......@@ -470,13 +472,11 @@ class BackendAOT(Backend):
compute_signatures_from_typeobjects(annot)
)
try:
locals_types = annotations["__locals__"][fdef.name]
except KeyError:
locals_types = None
locals_types = annotations["__locals__"].get(fdef.name, None)
returns = annotations["__returns__"].get(fdef.name, None)
return self._make_header_from_fdef_signatures(
fdef, signatures_as_lists_strings, locals_types
fdef, signatures_as_lists_strings, locals_types, returns
)
......@@ -496,6 +496,11 @@ class BackendJIT(Backend):
return []
def _make_header_from_fdef_signatures(
self, fdef, signatures_as_lists_strings, locals_types=None
self,
fdef,
signatures_as_lists_strings,
locals_types=None,
returns=None,
inline=False,
):
return []
......@@ -20,7 +20,7 @@ Internal API
import copy
import inspect
from transonic.analyses import extast
from transonic.analyses.extast import unparse, ast
from transonic.annotation import (
compute_pythran_type_from_type,
make_signatures_from_typehinted_func,
......@@ -204,10 +204,15 @@ class CythonBackend(BackendAOT):
return ["import cython\n\nimport numpy as np\ncimport numpy as np\n"]
def _make_header_from_fdef_signatures(
self, fdef, signatures_as_lists_strings, locals_types=None
self,
fdef,
signatures_as_lists_strings,
locals_types=None,
returns=None,
inline=False,
):
fdef = extast.ast.FunctionDef(
fdef = ast.FunctionDef(
name=fdef.name,
args=copy.deepcopy(fdef.args),
body=[],
......@@ -233,6 +238,9 @@ class CythonBackend(BackendAOT):
signatures_func.append("".join(ctypedef))
# change function parameters
if fdef.args.defaults:
name_start = ast.Name(id="*", ctx=ast.Param(), annotation=None)
fdef.args.defaults = [name_start] * len(fdef.args.defaults)
for name in fdef.args.args:
name.annotation = None
name.id = name_type_args[0] + " " + name.id
......@@ -247,5 +255,17 @@ class CythonBackend(BackendAOT):
)
signatures_func.append(f"@cython.locals({locals_types})\n")
signatures_func.append("cp" + extast.unparse(fdef).strip()[:-1] + "\n")
if inline:
inline = "inline "
def_keyword = "cdef"
else:
inline = ""
def_keyword = "cpdef"
if returns is not None:
returns = compute_cython_type_from_pythran_type(returns) + " "
else:
returns = ""
signatures_func.append(f"{def_keyword} {inline}{returns}{unparse(fdef).strip()[4:-1]}\n")
return signatures_func
......@@ -26,7 +26,12 @@ class PythranBackend(BackendAOT):
lines_header.append(f"export {name_variable}\n")
def _make_header_from_fdef_signatures(
self, fdef, signatures_as_lists_strings, locals_types=None
self,
fdef,
signatures_as_lists_strings,
locals_types=None,
returns=None,
inline=False,
):
signatures_func = set()
......
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