РЕДАКТИРОВАТЬ: это симпатичная ошибка. Я переместил обсуждение на https://github.com/sympy/sympy/issues/7457 а>
У меня есть программа на Python, которая использует sympy
для выполнения некоторых основных функций, связанных с пересечением линии и формы. Эту операцию необходимо выполнить несколько тысяч раз, и она довольно медленная при использовании sympy
чистых модулей Python по умолчанию.
Я попытался ускорить это, установив gmpy 2.0.3
(я также пробовал с gmpy 1.5
). Это приводит к некоторому ускорению кода, но при использовании multiprocessing
для дальнейшего ускорения программа вылетает с ошибкой TypeError
.
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\python27\lib\multiprocessing\pool.py", line 376, in _handle_results
task = get()
File "C:\python27\lib\site-packages\sympy\geometry\point.py", line 91, in __new__
for f in coords.atoms(Float)]))
File "C:\python27\lib\site-packages\sympy\simplify\simplify.py", line 3839, in nsimplify
return _real_to_rational(expr, tolerance)
File "C:\python27\lib\site-packages\sympy\simplify\simplify.py", line 3781, in _real_to_rational
r = nsimplify(float, rational=False)
File "C:\python27\lib\site-packages\sympy\simplify\simplify.py", line 3861, in nsimplify
exprval = expr.evalf(prec, chop=True)
File "C:\python27\lib\site-packages\sympy\core\evalf.py", line 1300, in evalf
re = C.Float._new(re, p)
File "C:\python27\lib\site-packages\sympy\core\numbers.py", line 673, in _new
obj._mpf_ = mpf_norm(_mpf_, _prec)
File "C:\python27\lib\site-packages\sympy\core\numbers.py", line 56, in mpf_norm
rv = mpf_normalize(sign, man, expt, bc, prec, rnd)
TypeError: ('argument is not an mpz', <class 'sympy.geometry.point.Point'>, (-7.07106781186548, -7.07106781186548))
Программа отлично работает при запуске в одном процессе с использованием gmpy
и при запуске без gmpy
с использованием multiprocessing.Pool
.
Кто-нибудь сталкивался с такой проблемой раньше? Программа ниже воспроизводит эту проблему:
import sympy
import multiprocessing
import numpy
def thread_function(func, data, output_progress=True, extra_kwargs=None, num_procs=None):
if extra_kwargs:
func = functools.partial(func, **extra_kwargs)
if not num_procs:
num_procs = multiprocessing.cpu_count()
pool = multiprocessing.Pool(processes=num_procs)
results = pool.map_async(func, data.T)
pool.close()
pool.join()
return results.get()
def test_fn(data):
x = data[0]
y = data[1]
circle = sympy.Circle((0,0), 10)
line = sympy.Line(sympy.Point(0,0), sympy.Point(x,y))
return line.intersection(circle)[0].evalf()
if __name__ == '__main__':
data = numpy.vstack((numpy.arange(1, 100), numpy.arange(1, 100)))
print thread_function(test_fn, data) #<--- this line causes the problem
# print [test_fn(data[:,i]) for i in xrange(data.shape[1])] #<--- this one runs without errors
pickle
? Возможно, объекты gmpy не поддаются обработке. - person asmeurer   schedule 03.05.2014