Read about our upcoming Code of Conduct on this issue

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

PYTHRANIZE_AT_IMPORT: fluidpythranize is needed

parent 325679d173c3
......@@ -46,7 +46,7 @@ class MyClass:
# pythran block (
# float[][] a, b;
# int n
# ) -> (result, a)
# ) -> (result)
# blabla
# blibli
......@@ -54,7 +54,7 @@ class MyClass:
# pythran block (
# float[][][] a, b;
# int n
# ) -> (result, a)
# ) -> (result)
result = np.zeros_like(a)
for _ in range(n):
result += a ** 2 + b ** 3
......@@ -64,18 +64,21 @@ class MyClass:
if __name__ == "__main__":
shape = 100, 100
shape = 2, 2
a = np.random.rand(*shape)
b = np.random.rand(*shape)
obj = MyClass(a, b)
obj.compute(10)
ret0 = obj.compute(10)
print("(is_pythranized, is_compiling, is_compiled)", (fp.is_pythranized, fp.is_compiling, fp.is_compiled))
if fp.is_pythranized:
ret = obj.compute(10)
assert np.allclose(ret, ret0), (ret - ret0)
fp.is_pythranized = False
ret1 = obj.compute(10)
fp.is_pythranized = True
assert np.allclose(ret, ret1)
assert np.allclose(ret, ret1), (ret - ret1)
print("allclose OK")
......@@ -27,6 +27,7 @@ import inspect
import importlib.util
import time
from pathlib import Path
import subprocess
from .util import (
get_module_name,
......@@ -35,6 +36,7 @@ from .util import (
import_from_path,
ext_suffix,
has_to_build,
modification_date,
)
from .annotation import (
......@@ -196,28 +198,55 @@ class FluidPythran:
self.is_compiling = False
if "." in module_name:
package, module = module_name.rsplit(".", 1)
module_pythran = package + ".__pythran__._" + module
package, module_short_name = module_name.rsplit(".", 1)
module_pythran = package + ".__pythran__._" + module_short_name
else:
module_short_name = module_name
module_pythran = "__pythran__._" + module_name
path_mod = Path(frame.filename)
path_pythran = path_mod.parent / "__pythran__" / ("_" + module_short_name + ".py")
self.path_extension = path_ext = Path(path_pythran).with_suffix(ext_suffix)
if has_to_pythranize_at_import() and path_mod.exists():
if has_to_build(path_pythran, path_mod):
if path_pythran.exists():
time_pythran = modification_date(path_pythran)
else:
time_pythran = 0
print(f"running fluidpythran on file {path_mod}... ", end="")
# better to do this in another process because the file is already run...
subprocess.call(["fluidpythran", "-np", str(path_mod)])
print("Done!")
time_pythran_after = modification_date(path_pythran)
# We have to touch the files to signal that they are up-to-date
if time_pythran_after == time_pythran:
if not has_to_build(path_ext, path_pythran):
path_pythran.touch()
if path_ext.exists():
path_ext.touch()
else:
path_pythran.touch()
try:
self.module_pythran = importlib.import_module(module_pythran)
except ModuleNotFoundError:
self.is_pythranized = False
self.is_compiled = False
else:
self.is_pythranized = True
self.is_compiled = hasattr(self.module_pythran, "__pythran__")
self.is_compiling = False
if has_to_pythranize_at_import():
path_pythran_file = self.module_pythran.__file__
self.path_extension = Path(path_pythran_file).with_suffix(
ext_suffix
)
if has_to_build(self.path_extension, path_pythran_file):
self.process = compile_pythran_file(path_pythran_file)
if has_to_build(self.path_extension, path_pythran):
self.process = compile_pythran_file(path_pythran)
self.is_compiling = True
self.is_compiled = False
module = inspect.getmodule(frame[0])
try:
module.__pythran__ = self.module_pythran.__pythran__
except AttributeError:
......@@ -226,10 +255,7 @@ class FluidPythran:
module.__fluidpythran__ = self.module_pythran.__fluidpythran__
except AttributeError:
pass
except ModuleNotFoundError:
self.is_pythranized = False
self.is_compiled = False
else:
if hasattr(self.module_pythran, "arguments_blocks"):
self.arguments_blocks = getattr(
self.module_pythran, "arguments_blocks"
......
......@@ -38,14 +38,14 @@ def run():
"""
args = parse_args()
if not args.path:
print("No python files given. Nothing to do! ✨ 🍰 ✨.")
return
if args.version:
print(__version__)
return
if not args.path:
print("No python files given. Nothing to do! ✨ 🍰 ✨.")
return
if args.verbose is None:
set_log_level("info")
elif args.verbose > 0:
......
......@@ -29,6 +29,8 @@ class TestsInit(unittest.TestCase):
if cls.path_ext.exists():
cls.path_ext.unlink()
os.environ.pop("PYTHRANIZE_AT_IMPORT")
def __test_fluidpythranized(self):
os.environ.pop("PYTHRANIZE_AT_IMPORT")
......
import sys
from shutil import rmtree
import time
from . import path_data_tests
......@@ -23,20 +24,40 @@ def test_create_pythran_files():
run()
def test_create_pythran_simple():
sys.argv = "fluidpythran --version".split()
run()
sys.argv = ["fluidpythran"]
run()
def test_create_pythran_classic():
if path_dir_out.exists():
rmtree(path_dir_out)
path_file = path_data_tests / "classic.py"
sys.argv = f"fluidpythran -v -np {path_file}".split()
sys.argv = f"fluidpythran -np -v {path_file}".split()
run()
print("after first build")
run()
time.sleep(0.02)
path_file.touch()
print("after touch")
run()
path_file_pythran = path_data_tests / "__pythran__/_classic.py"
path_file_pythran.unlink()
print("after unlink")
run()
sys.argv = f"fluidpythran {path_file}".split()
run()
sys.argv = f"fluidpythran -np {path_file_pythran}".split()
run()
......@@ -29,6 +29,10 @@ exclude_lines =
raise NotImplementedError
raise ImportError
except ImportError:
except ModuleNotFoundError:
except IndexError:
except AttributeError:
except KeyError:
if test:
if check:
if __name__ == "__main__":
......
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