Python 尝试并行化Sage代码会使用@parallel decorator或multiprocessing.Pool创建“thread\u suspend failed”和“Unhandled SIGABRT”错误
我有一些Sage代码,我正在尝试并行化,但遇到了线程挂起失败和未处理的SIGABRT错误的问题。我曾尝试过使用Python的multiprocessing.Pool类,但后来按照kcrisman的建议修改为使用Sage的@parallel,但无论我使用哪个类,都会出现相同的错误 我似乎无法创建一个最小的工作示例来重现这些错误,因此下面是我的代码的相关片段:Python 尝试并行化Sage代码会使用@parallel decorator或multiprocessing.Pool创建“thread\u suspend failed”和“Unhandled SIGABRT”错误,python,multiprocessing,sage,Python,Multiprocessing,Sage,我有一些Sage代码,我正在尝试并行化,但遇到了线程挂起失败和未处理的SIGABRT错误的问题。我曾尝试过使用Python的multiprocessing.Pool类,但后来按照kcrisman的建议修改为使用Sage的@parallel,但无论我使用哪个类,都会出现相同的错误 我似乎无法创建一个最小的工作示例来重现这些错误,因此下面是我的代码的相关片段: @parallel def calculate_translation(direction, interval, tr): g =
@parallel
def calculate_translation(direction, interval, tr):
g = Graphics()
translations = {}
discontinuities = tr.intervals[interval]
num_discontinuities = len(discontinuities)
(left_lbl, left_pt) = tr.interval_to_surface(interval, discontinuities[0])
left_offset = tr.T.offsets[left_lbl]
g += circle((left_offset[0] + left_pt[0], left_offset[1] + left_pt[1]),
0.05, color='purple', fill=true)
for i in xrange(1, num_discontinuities):
(right_lbl, right_pt) = tr.interval_to_surface(interval, discontinuities[i])
right_offset = tr.T.offsets[right_lbl]
g += circle((right_offset[0] + right_pt[0], right_offset[1] + right_pt[1]),
0.05, color='purple', fill=true)
# Determine the midpoint of the interval, then find
# the corresponding point on the surface.
mid_pt = (discontinuities[i-1] + discontinuities[i]) / 2
(sq_lbl, pt0) = tr.interval_to_surface(interval, mid_pt, top_square = true)
square = tr.T.surface.squares[sq_lbl]
(x, y) = pt0
# Determine where the corresponding square sits in the
# picture. Draw a red circle at the midpoint, where
# our geodesic starts.
(x0, y0) = tr.T.offsets[sq_lbl]
g += circle((x0 + x, y0 + y), 0.05, color='red', fill=true)
while true:
# We are starting from init_square
init_square = square.name
# Get the coordinates (inside init_square) of our starting point.
(x0, y0) = pt0
# Get the coordinates (inside init_square) of the terminal point,
# before entering the next square, and also record the new square.
(x1, y1, next_square) = square.nextpt(pt0, direction)
# Determine the offsets of the square (for drawing)
(x_offset, y_offset) = tr.T.offsets[init_square]
# Draw the piece of the geodesic inside of init_square
g += line([(x0 + x_offset, y0 + y_offset),
(x1 + x_offset, y1 + y_offset)],
color='blue')
if y1 == 1:
# If we hit the top of init_square, check to
# see if we've received one of the intervals.
if tr.bottom_squares.count(init_square) > 0:
# bottom_squares records the squares, in
# the lower copies of the table, whose
# upper edge lies on an interval. If
# we've started from such a square and hit
# its top edge, then we've returned to our
# interval.
terminal_square = init_square
(x_terminal, y_terminal) = (x1, y1)
break
elif tr.top_squares.count(next_square.name) > 0:
# If the next square we would move
# into lives above the interval, then
# stop. We need to reset the point so
# that we can use interval_to_surface
# later.
terminal_square = next_square.name
pt0 = TReturn.reset_point((x1, y1), direction)
(x_terminal, y_terminal) = pt0
break
# If we did not yet hit one of our intervals,
# rinse and repeat.
pt0 = TReturn.reset_point((x1, y1), direction)
square = next_square
# Out of while loop, still in for loop.
# have terminal_square, and (x_terminal, y_terminal) point
(image_interval, image_pt) = tr.surface_to_interval(terminal_square,
(x_terminal, y_terminal))
# Add image point to the graph.
(x_offset, y_offset) = tr.T.offsets[terminal_square]
g += circle((x_offset + x_terminal, y_offset + y_terminal), 0.05,
color='orange', fill=true)
distance_to_left = mid_pt - discontinuities[i-1]
translation = image_pt - distance_to_left
translation = translation.full_simplify()
translations[i] = (image_interval, translation)
return (g, interval, translations)
class TReturn:
# Other methods are defined, but not relevant.
def parallel_calculate_translations(self):
graphic = Graphics()
job_args = [(self.angle, key, self) for key in self.intervals.keys()]
results = [x[1] for x in calculate_translation(job_args)]
## I tried using multiprocessing.Pool as well, but the same errors occurred.
# pool = Pool(2)
# results = pool.map(calculate_translation_helper, job_args)
# pool.close()
# pool.join()
for i in xrange(0, len(results)):
(g, interval, translation) = results[i]
graphic += g
self.translations[interval] = translation
return graphic
运行代码时,将打印以下内容:
thread_suspend failed
Traceback (most recent call last):
File "TReturn.py", line 1234, in <module>
tr = TReturn(_sage_const_2 , _sage_const_0p2354 , parallelize = true)
File "TReturn.py", line 306, in __init__
self.calculate_instance_variables(generations, angle, parallelize)
File "TReturn.py", line 517, in calculate_instance_variables
self.iet_trajectories = self.parallel_calculate_translations()
File "TReturn.py", line 954, in parallel_calculate_translations
results = pool.map(calculate_translation_helper, job_args)
File "/Applications/Sage-6.3.app/Contents/Resources/sage/local/lib/python/multiprocessing/pool.py", line 251, in map
仅供参考,您使用的不是Sage的东西,而是?此外,即使您可以将实际代码发布到某个代码片段站点,这也会对人们有所帮助;这似乎不太可能是一个纯粹的Python bug,而是您正在使用的任何Sage代码都被要求做太多的事情……感谢您的评论;实际上我完全忘记了@parallel decorator。但是,修改代码以使用它仍然会产生相同的错误。现在提供了一个代码片段。
thread_suspend failed
------------------------------------------------------------------------
Unhandled SIGABRT: An abort() occurred in Sage.
This probably occurred because a *compiled* component of Sage has a bug
in it and is not properly wrapped with sig_on(), sig_off().
Sage will now terminate.
------------------------------------------------------------------------