Skip to content

Commit 359e933

Browse files
authored
Merge pull request #213 from isuruf/pickle
Enable pickling for LLVMDouble class
2 parents fefb5f4 + 08226b9 commit 359e933

File tree

6 files changed

+56
-5
lines changed

6 files changed

+56
-5
lines changed

.travis.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ os:
66
- linux
77
- osx
88
sudo: false
9+
osx_image: xcode6.4
910
addons:
1011
apt:
1112
sources:
@@ -52,7 +53,7 @@ matrix:
5253
packages:
5354
- binutils-dev
5455
- g++-4.8
55-
- env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.5" WITH_LLVM="yes" WITH_SCIPY="yes"
56+
- env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.5" WITH_LLVM="3.8" WITH_SCIPY="yes"
5657
compiler: clang
5758
os: linux
5859
addons:
@@ -85,6 +86,13 @@ matrix:
8586
compiler: gcc
8687
os: linux
8788

89+
before_install:
90+
- |
91+
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
92+
command curl -sSL https://rvm.io/mpapis.asc | gpg --import -;
93+
rvm get head || true
94+
fi
95+
8896
install:
8997
- export PYTHON_SOURCE_DIR=`pwd`
9098
- export TEST_CPP="no"

symengine/lib/symengine.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ cdef extern from "<symengine/llvm_double.h>" namespace "SymEngine":
972972
LLVMDoubleVisitor() nogil
973973
void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except +
974974
void call(double *r, const double *x) nogil
975+
const string& dumps() nogil
976+
void loads(const string&) nogil
975977

976978
cdef extern from "<symengine/series.h>" namespace "SymEngine":
977979
cdef cppclass SeriesCoeffInterface:

symengine/lib/symengine_wrapper.pyx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4369,7 +4369,7 @@ cdef class _Lambdify(object):
43694369
cdef vector[int] accum_out_sizes
43704370
cdef object numpy_dtype
43714371

4372-
def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False):
4372+
def __init__(self, args, *exprs, cppbool real=True, order='C', cppbool cse=False, cppbool _load=False):
43734373
cdef:
43744374
Basic e_
43754375
size_t ri, ci, nr, nc
@@ -4378,6 +4378,13 @@ cdef class _Lambdify(object):
43784378
symengine.vec_basic args_, outs_
43794379
vector[int] out_sizes
43804380

4381+
if _load:
4382+
self.args_size, self.tot_out_size, self.out_shapes, self.real, \
4383+
self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, \
4384+
llvm_function = args
4385+
self._load(llvm_function)
4386+
return
4387+
43814388
args = np.asanyarray(args)
43824389
self.args_size = args.size
43834390
exprs = tuple(np.asanyarray(expr) for expr in exprs)
@@ -4414,6 +4421,9 @@ cdef class _Lambdify(object):
44144421
cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse):
44154422
raise ValueError("Not supported")
44164423

4424+
cdef _load(self, const string &s):
4425+
raise ValueError("Not supported")
4426+
44174427
cpdef unsafe_real(self,
44184428
double[::1] inp, double[::1] out,
44194429
int inp_offset=0, int out_offset=0):
@@ -4625,6 +4635,18 @@ IF HAVE_SYMENGINE_LLVM:
46254635
self.lambda_double.resize(1)
46264636
self.lambda_double[0].init(args_, outs_, cse)
46274637

4638+
cdef _load(self, const string &s):
4639+
self.lambda_double.resize(1)
4640+
self.lambda_double[0].loads(s)
4641+
4642+
def __reduce__(self):
4643+
"""
4644+
Interface for pickle. Note that the resulting object is platform dependent.
4645+
"""
4646+
cdef bytes s = self.lambda_double[0].dumps()
4647+
return llvm_loading_func, (self.args_size, self.tot_out_size, self.out_shapes, self.real, \
4648+
self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, s)
4649+
46284650
cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=0, int out_offset=0):
46294651
self.lambda_double[0].call(&out[out_offset], &inp[inp_offset])
46304652

@@ -4639,6 +4661,8 @@ IF HAVE_SYMENGINE_LLVM:
46394661
addr2 = cast(<size_t>&self.lambda_double[0], c_void_p)
46404662
return create_low_level_callable(self, addr1, addr2)
46414663

4664+
def llvm_loading_func(*args):
4665+
return LLVMDouble(args, _load=True)
46424666

46434667
def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', as_scipy=False, cse=False):
46444668
"""

symengine/tests/test_pickling.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from symengine import symbols, sin, sinh, have_numpy, have_llvm
2+
import pickle
3+
import unittest
4+
5+
@unittest.skipUnless(have_llvm, "No LLVM support")
6+
@unittest.skipUnless(have_numpy, "Numpy not installed")
7+
def test_llvm_double():
8+
import numpy as np
9+
from symengine import Lambdify
10+
args = x, y, z = symbols('x y z')
11+
expr = sin(sinh(x+y) + z)
12+
l = Lambdify(args, expr, cse=True, backend='llvm')
13+
ss = pickle.dumps(l)
14+
ll = pickle.loads(ss)
15+
inp = [1, 2, 3]
16+
assert np.allclose(l(inp), ll(inp))
17+

symengine/tests/test_printing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def test_ccode():
99
assert ccode(x**3) == "pow(x, 3)"
1010
assert ccode(x**(y**3)) == "pow(x, pow(y, 3))"
1111
assert ccode(x**-1.0) == "pow(x, -1.0)"
12-
assert ccode(Max(x, x*x)) == "max(x, pow(x, 2))"
12+
assert ccode(Max(x, x*x)) == "fmax(x, pow(x, 2))"
1313
assert ccode(sin(x)) == "sin(x)"
1414
assert ccode(Integer(67)) == "67"
1515
assert ccode(Integer(-1)) == "-1"
@@ -24,4 +24,4 @@ def test_CCodePrinter():
2424
assert myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]), "larry") == "larry[0] = x;\nlarry[1] = y;"
2525
raises(TypeError, lambda: myprinter.doprint(sin(x), Integer))
2626
raises(RuntimeError, lambda: myprinter.doprint(MutableDenseMatrix(1, 2, [x, y])))
27-
27+

symengine_version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2f5ff9db9ff511ee243438a85ea8e2da2d05af39
1+
fff6755331226a08f0b14571bfbce2b23001d911

0 commit comments

Comments
 (0)