From 221ccac3e9e5196384f4af08f42475aa37266bae Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 15:30:57 -0600 Subject: [PATCH 1/8] Enable pickling for LLVMDouble class --- symengine/lib/symengine.pxd | 2 ++ symengine/lib/symengine_wrapper.pyx | 26 +++++++++++++++++++++++++- symengine/tests/test_pickling.py | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 symengine/tests/test_pickling.py diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 5b717d296..adccf6c3a 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -972,6 +972,8 @@ cdef extern from "" namespace "SymEngine": LLVMDoubleVisitor() nogil void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except + void call(double *r, const double *x) nogil + const string& dumps() nogil + void loads(const string&) nogil cdef extern from "" namespace "SymEngine": cdef cppclass SeriesCoeffInterface: diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index de0a622f9..c3f61e575 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4369,7 +4369,7 @@ cdef class _Lambdify(object): cdef vector[int] accum_out_sizes cdef object numpy_dtype - def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False): + def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False, cppbool load=False): cdef: Basic e_ size_t ri, ci, nr, nc @@ -4378,6 +4378,13 @@ cdef class _Lambdify(object): symengine.vec_basic args_, outs_ vector[int] out_sizes + if load: + self.args_size, self.tot_out_size, self.out_shapes, self.real, \ + self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, \ + llvm_function = args + self._load(llvm_function) + return + args = np.asanyarray(args) self.args_size = args.size exprs = tuple(np.asanyarray(expr) for expr in exprs) @@ -4414,6 +4421,9 @@ cdef class _Lambdify(object): cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): raise ValueError("Not supported") + cdef _load(self, const string &s): + raise ValueError("Not supported") + cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=0, int out_offset=0): @@ -4625,6 +4635,18 @@ IF HAVE_SYMENGINE_LLVM: self.lambda_double.resize(1) self.lambda_double[0].init(args_, outs_, cse) + cdef _load(self, const string &s): + self.lambda_double.resize(1) + self.lambda_double[0].loads(s) + + def __reduce__(self): + """ + Interface for pickle. Note that the resulting object is platform dependent. + """ + cdef bytes s = self.lambda_double[0].dumps() + return llvm_loading_func, (self.args_size, self.tot_out_size, self.out_shapes, self.real, \ + self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, s) + cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=0, int out_offset=0): self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) @@ -4639,6 +4661,8 @@ IF HAVE_SYMENGINE_LLVM: addr2 = cast(&self.lambda_double[0], c_void_p) return create_low_level_callable(self, addr1, addr2) + def llvm_loading_func(*args): + return LLVMDouble(args, load=True) def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', as_scipy=False, cse=False): """ diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py new file mode 100644 index 000000000..85f28cebb --- /dev/null +++ b/symengine/tests/test_pickling.py @@ -0,0 +1,15 @@ +from symengine import symbols, sin, sinh, Lambdify, have_numpy +import pickle +import unittest + +@unittest.skipUnless(have_numpy, "Numpy not installed") +def test_llvm_double(): + import numpy as np + args = x, y, z = symbols('x y z') + expr = sin(sinh(x+y) + z) + l = Lambdify(args, expr, cse=True, backend='llvm') + ss = pickle.dumps(l) + ll = pickle.loads(ss) + inp = [1, 2, 3] + assert np.allclose(l(inp), ll(inp)) + From 43026f0ce2de55453af9ad77587b3afb2e71b75e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 15:31:55 -0600 Subject: [PATCH 2/8] Bump symengine version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index ac91982c7..781d7e63b 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -2f5ff9db9ff511ee243438a85ea8e2da2d05af39 +fff6755331226a08f0b14571bfbce2b23001d911 From 93dd6c10f23492febf0f68365f904b49977516ad Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 15:35:36 -0600 Subject: [PATCH 3/8] Fix failing test --- symengine/tests/test_printing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/tests/test_printing.py b/symengine/tests/test_printing.py index 6d4628cb4..d4314425a 100644 --- a/symengine/tests/test_printing.py +++ b/symengine/tests/test_printing.py @@ -9,7 +9,7 @@ def test_ccode(): assert ccode(x**3) == "pow(x, 3)" assert ccode(x**(y**3)) == "pow(x, pow(y, 3))" assert ccode(x**-1.0) == "pow(x, -1.0)" - assert ccode(Max(x, x*x)) == "max(x, pow(x, 2))" + assert ccode(Max(x, x*x)) == "fmax(x, pow(x, 2))" assert ccode(sin(x)) == "sin(x)" assert ccode(Integer(67)) == "67" assert ccode(Integer(-1)) == "-1" @@ -24,4 +24,4 @@ def test_CCodePrinter(): assert myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]), "larry") == "larry[0] = x;\nlarry[1] = y;" raises(TypeError, lambda: myprinter.doprint(sin(x), Integer)) raises(RuntimeError, lambda: myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]))) - \ No newline at end of file + From 77efc6331e38f840a9b58321997cb742da027915 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 15:44:54 -0600 Subject: [PATCH 4/8] Skip test if no llvm --- symengine/tests/test_pickling.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index 85f28cebb..c6c3dd985 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,7 +1,8 @@ -from symengine import symbols, sin, sinh, Lambdify, have_numpy +from symengine import symbols, sin, sinh, Lambdify, have_numpy, have_llvm import pickle import unittest +@unittest.skipUnless(have_llvm, "No LLVM support") @unittest.skipUnless(have_numpy, "Numpy not installed") def test_llvm_double(): import numpy as np From 28247b90668a212fbf355641b1250fdda45dd554 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 15:51:40 -0600 Subject: [PATCH 5/8] Fix import error --- symengine/tests/test_pickling.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index c6c3dd985..b7f14a181 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,4 +1,4 @@ -from symengine import symbols, sin, sinh, Lambdify, have_numpy, have_llvm +from symengine import symbols, sin, sinh, have_numpy, have_llvm import pickle import unittest @@ -6,6 +6,7 @@ @unittest.skipUnless(have_numpy, "Numpy not installed") def test_llvm_double(): import numpy as np + from symengine import Lambdify args = x, y, z = symbols('x y z') expr = sin(sinh(x+y) + z) l = Lambdify(args, expr, cse=True, backend='llvm') From 48bb041aa51133a1312d0d8851393050e1f613fa Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 16:02:00 -0600 Subject: [PATCH 6/8] Change load->_load --- symengine/lib/symengine_wrapper.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c3f61e575..685bb6bd8 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4369,7 +4369,7 @@ cdef class _Lambdify(object): cdef vector[int] accum_out_sizes cdef object numpy_dtype - def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False, cppbool load=False): + def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False, cppbool _load=False): cdef: Basic e_ size_t ri, ci, nr, nc @@ -4378,7 +4378,7 @@ cdef class _Lambdify(object): symengine.vec_basic args_, outs_ vector[int] out_sizes - if load: + if _load: self.args_size, self.tot_out_size, self.out_shapes, self.real, \ self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, \ llvm_function = args @@ -4662,7 +4662,7 @@ IF HAVE_SYMENGINE_LLVM: return create_low_level_callable(self, addr1, addr2) def llvm_loading_func(*args): - return LLVMDouble(args, load=True) + return LLVMDouble(args, _load=True) def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', as_scipy=False, cse=False): """ From 3fdbe7b827f0b88d3a3f175f613ab6403ea29c01 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 18:05:23 -0600 Subject: [PATCH 7/8] Fix travis tests --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f81bb2ee..c2243838e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ matrix: packages: - binutils-dev - g++-4.8 - - env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.5" WITH_LLVM="yes" WITH_SCIPY="yes" + - env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.5" WITH_LLVM="3.8" WITH_SCIPY="yes" compiler: clang os: linux addons: @@ -85,6 +85,13 @@ matrix: compiler: gcc os: linux +before_install: +- | + if [ "${TRAVIS_OS_NAME}" == "osx" ]; then + command curl -sSL https://rvm.io/mpapis.asc | gpg --import -; + rvm get head || true + fi + install: - export PYTHON_SOURCE_DIR=`pwd` - export TEST_CPP="no" From 08226b9e363e57652bf8c86eabe55347f5d6c350 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 6 Feb 2018 18:39:09 -0600 Subject: [PATCH 8/8] Add osx_image --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c2243838e..0fe382d3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ os: - linux - osx sudo: false +osx_image: xcode6.4 addons: apt: sources: