From bbd75a369714b68efb59bc6e575a05adf2655796 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 3 Mar 2020 16:17:11 -0600 Subject: [PATCH 1/9] Support pymbolic.interop.symengine.make_cse --- pymbolic/interop/common.py | 4 ---- pymbolic/interop/symengine.py | 17 +++++++++++++++++ pymbolic/interop/sympy.py | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pymbolic/interop/common.py b/pymbolic/interop/common.py index 458c103..568a364 100644 --- a/pymbolic/interop/common.py +++ b/pymbolic/interop/common.py @@ -108,10 +108,6 @@ class SympyLikeToPymbolicMapper(SympyLikeMapperBase): return prim.Derivative(self.rec(expr.expr), tuple(v.name for v in expr.variables)) - def map_CSE(self, expr): # noqa - return prim.CommonSubexpression( - self.rec(expr.args[0]), expr.prefix) - def map_UnevaluatedExpr(self, expr): # noqa return self.rec(expr.args[0]) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index e7491a0..d6fd5f1 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -77,6 +77,13 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): # For builtin functions return type(expr).__name__ + def not_supported(self, expr): # noqa + if isinstance(expr, symengine.Function) and \ + self.function_name(expr) == "CSE": + return prim.CommonSubexpression( + self.rec(expr.args[0]), expr._sympy_().prefix) + return SympyLikeToPymbolicMapper.not_supported(self, expr) + # }}} @@ -93,4 +100,14 @@ class PymbolicToSymEngineMapper(PymbolicToSympyLikeMapper): # }}} + +def make_cse(arg, prefix=None): + # SymEngine's classes can't be inherited, but there's a + # mechanism to create one based on SymPy's ones which stores + # the SymPy object inside the C++ object. + # This SymPy object is later retrieved to get the prefix + from pymbolic.interop.sympy import make_cse as make_cse_sympy + sympy_result = make_cse_sympy(arg, prefix=prefix) + return symengine.sympify(sympy_result) + # vim: fdm=marker diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index cce923b..4d6dd9b 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -68,6 +68,10 @@ class SympyToPymbolicMapper(SympyLikeToPymbolicMapper): tuple(self.rec(i) for i in expr.args[1:]) ) + def map_CSE(self, expr): # noqa + return prim.CommonSubexpression( + self.rec(expr.args[0]), expr.prefix) + # }}} -- GitLab From 9b5e9b70ffffccd66e4329d4e093ea37b3b4e9f0 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 3 Mar 2020 18:17:07 -0600 Subject: [PATCH 2/9] Add scope and fix conversions --- pymbolic/interop/symengine.py | 15 ++++++++++----- pymbolic/interop/sympy.py | 5 +++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index d6fd5f1..2150cc7 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -80,8 +80,9 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): def not_supported(self, expr): # noqa if isinstance(expr, symengine.Function) and \ self.function_name(expr) == "CSE": + sympy_expr = expr._sympy_() return prim.CommonSubexpression( - self.rec(expr.args[0]), expr._sympy_().prefix) + self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) return SympyLikeToPymbolicMapper.not_supported(self, expr) # }}} @@ -101,13 +102,17 @@ class PymbolicToSymEngineMapper(PymbolicToSympyLikeMapper): # }}} -def make_cse(arg, prefix=None): +def make_cse(arg, prefix=None, scope=None): # SymEngine's classes can't be inherited, but there's a # mechanism to create one based on SymPy's ones which stores # the SymPy object inside the C++ object. # This SymPy object is later retrieved to get the prefix - from pymbolic.interop.sympy import make_cse as make_cse_sympy - sympy_result = make_cse_sympy(arg, prefix=prefix) - return symengine.sympify(sympy_result) + # _args is set manually to avoid SymEngine->SymPy->SymEngine casts + from sympy import Function as SymPyFunction + f = SymPyFunction("CSE")() + f._args = (arg,) + f.scope = scope + f.prefix = prefix + return symengine.sympify(f) # vim: fdm=marker diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index 4d6dd9b..393894e 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -70,7 +70,7 @@ class SympyToPymbolicMapper(SympyLikeToPymbolicMapper): def map_CSE(self, expr): # noqa return prim.CommonSubexpression( - self.rec(expr.args[0]), expr.prefix) + self.rec(expr.args[0]), expr.prefix, expr.scope) # }}} @@ -98,9 +98,10 @@ class CSE(sympy.Function): nargs = 1 -def make_cse(arg, prefix=None): +def make_cse(arg, prefix=None, scope=None): result = CSE(arg) result.prefix = prefix + result.scope = scope return result -- GitLab From 04651f38012b05ef8490b18c6aad83f87488174a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Mar 2020 20:44:06 +0100 Subject: [PATCH 3/9] Revert to using sympy --- pymbolic/interop/symengine.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index 2150cc7..d2add7b 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -107,12 +107,8 @@ def make_cse(arg, prefix=None, scope=None): # mechanism to create one based on SymPy's ones which stores # the SymPy object inside the C++ object. # This SymPy object is later retrieved to get the prefix - # _args is set manually to avoid SymEngine->SymPy->SymEngine casts - from sympy import Function as SymPyFunction - f = SymPyFunction("CSE")() - f._args = (arg,) - f.scope = scope - f.prefix = prefix - return symengine.sympify(f) + from pymbolic.interop.sympy import make_cse as make_cse_sympy + sympy_result = make_cse_sympy(arg, prefix=prefix, scope=scope) + return symengine.sympify(sympy_result) # vim: fdm=marker -- GitLab From d3ea43def9701bbc2488f4dd7e0c36539f26c3b7 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Mar 2020 18:53:15 -0600 Subject: [PATCH 4/9] Avoid conversions if possible --- .test-py2.yml | 2 +- .test-py3.yml | 2 +- pymbolic/interop/symengine.py | 13 ++++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.test-py2.yml b/.test-py2.yml index b53749c..8cf7b7a 100644 --- a/.test-py2.yml +++ b/.test-py2.yml @@ -9,5 +9,5 @@ dependencies: - conda-forge::numpy - conda-forge::sympy - python=2.7 - - symengine::python-symengine=0.3.0 + - symengine::python-symengine=0.6.0 - maxima diff --git a/.test-py3.yml b/.test-py3.yml index bd1f2bd..e05ae79 100644 --- a/.test-py3.yml +++ b/.test-py3.yml @@ -7,6 +7,6 @@ dependencies: - conda-forge::numpy - conda-forge::sympy - python=3.6 - - symengine::python-symengine=0.3.0 + - symengine::python-symengine=0.6.0 # - pexpect # - maxima diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index d2add7b..64d4623 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -78,11 +78,15 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): return type(expr).__name__ def not_supported(self, expr): # noqa - if isinstance(expr, symengine.Function) and \ + from symengine.lib.symengine_wrapper import PyFunction + if isinstance(expr, PyFunction) and \ self.function_name(expr) == "CSE": sympy_expr = expr._sympy_() return prim.CommonSubexpression( self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) + elif isinstance(expr, symengine.Function) and \ + self.function_name(expr) == "CSE": + return prim.CommonSubexpression(self.rec(expr.args[0])) return SympyLikeToPymbolicMapper.not_supported(self, expr) # }}} @@ -102,11 +106,18 @@ class PymbolicToSymEngineMapper(PymbolicToSympyLikeMapper): # }}} +CSE = symengine.Function("CSE") + + def make_cse(arg, prefix=None, scope=None): # SymEngine's classes can't be inherited, but there's a # mechanism to create one based on SymPy's ones which stores # the SymPy object inside the C++ object. # This SymPy object is later retrieved to get the prefix + # These conversions between SymPy and SymEngine are expensive, + # so use it only if necessary. + if prefix is None and scope is None: + return CSE(arg) from pymbolic.interop.sympy import make_cse as make_cse_sympy sympy_result = make_cse_sympy(arg, prefix=prefix, scope=scope) return symengine.sympify(sympy_result) -- GitLab From f839872564e22a5c46e52be7a9484630bfe82231 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Mar 2020 19:16:47 -0600 Subject: [PATCH 5/9] Fix conda env --- .test-py2.yml | 3 +-- .test-py3.yml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.test-py2.yml b/.test-py2.yml index 8cf7b7a..62516d5 100644 --- a/.test-py2.yml +++ b/.test-py2.yml @@ -1,6 +1,5 @@ name: py2 channels: - - symengine - conda-forge - defaults dependencies: @@ -9,5 +8,5 @@ dependencies: - conda-forge::numpy - conda-forge::sympy - python=2.7 - - symengine::python-symengine=0.6.0 + - python-symengine=0.6.0 - maxima diff --git a/.test-py3.yml b/.test-py3.yml index e05ae79..c17b40c 100644 --- a/.test-py3.yml +++ b/.test-py3.yml @@ -1,12 +1,11 @@ name: py3 channels: - - symengine - conda-forge - defaults dependencies: - conda-forge::numpy - conda-forge::sympy - python=3.6 - - symengine::python-symengine=0.6.0 + - python-symengine=0.6.0 # - pexpect # - maxima -- GitLab From 3dcef9ab66abdc8451b9eb8a2d453494881766c7 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Mar 2020 04:14:52 +0100 Subject: [PATCH 6/9] Pylint complaints when importing from Cython files --- pymbolic/interop/symengine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index 64d4623..1474ed7 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -78,9 +78,9 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): return type(expr).__name__ def not_supported(self, expr): # noqa - from symengine.lib.symengine_wrapper import PyFunction - if isinstance(expr, PyFunction) and \ - self.function_name(expr) == "CSE": + from symengine.lib.symengine_wrapper import PyFunction # noqa: E0611 + if isinstance(expr, PyFunction) and \ # noqa: E0611 + self.function_name(expr) == "CSE": # noqa: E0611 sympy_expr = expr._sympy_() return prim.CommonSubexpression( self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) -- GitLab From 608b299252475fc09d97b080ddada3db39900886 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Mar 2020 04:21:52 +0100 Subject: [PATCH 7/9] Update symengine.py --- pymbolic/interop/symengine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index 1474ed7..5bf67c9 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -79,7 +79,7 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): def not_supported(self, expr): # noqa from symengine.lib.symengine_wrapper import PyFunction # noqa: E0611 - if isinstance(expr, PyFunction) and \ # noqa: E0611 + if isinstance(expr, PyFunction) and \ self.function_name(expr) == "CSE": # noqa: E0611 sympy_expr = expr._sympy_() return prim.CommonSubexpression( -- GitLab From e673a8fa247a83ee009019ab4f0cf95e522aabf1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Mar 2020 04:30:36 +0100 Subject: [PATCH 8/9] Use pylint syntax --- pymbolic/interop/symengine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index 5bf67c9..8a2211e 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -78,9 +78,9 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): return type(expr).__name__ def not_supported(self, expr): # noqa - from symengine.lib.symengine_wrapper import PyFunction # noqa: E0611 + from symengine.lib.symengine_wrapper import PyFunction # pylint: disable=E0611 if isinstance(expr, PyFunction) and \ - self.function_name(expr) == "CSE": # noqa: E0611 + self.function_name(expr) == "CSE": # pylint: disable=E0611 sympy_expr = expr._sympy_() return prim.CommonSubexpression( self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) -- GitLab From 7c84b809883e2377715db6fcf9fdc2d4d4ee54b4 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Mar 2020 21:32:56 -0600 Subject: [PATCH 9/9] Fix flake8 now --- pymbolic/interop/symengine.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index 8a2211e..a984400 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -78,9 +78,10 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): return type(expr).__name__ def not_supported(self, expr): # noqa - from symengine.lib.symengine_wrapper import PyFunction # pylint: disable=E0611 + from symengine.lib.symengine_wrapper import \ + PyFunction # pylint: disable=E0611 if isinstance(expr, PyFunction) and \ - self.function_name(expr) == "CSE": # pylint: disable=E0611 + self.function_name(expr) == "CSE": # pylint: disable=E0611 sympy_expr = expr._sympy_() return prim.CommonSubexpression( self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) -- GitLab