Parallelize now reseeds random number generators after fork()
Bugfix -- AxisItem enforces tick boundaries more strictly
This commit is contained in:
parent
3d71a1f555
commit
73e94f543c
@ -538,6 +538,10 @@ class AxisItem(GraphicsWidget):
|
||||
xScale = bounds.width() / dif
|
||||
offset = self.range[0] * xScale
|
||||
|
||||
xRange = [x * xScale - offset for x in self.range]
|
||||
xMin = min(xRange)
|
||||
xMax = max(xRange)
|
||||
|
||||
prof.mark('init')
|
||||
|
||||
tickPositions = [] # remembers positions of previously drawn ticks
|
||||
@ -545,6 +549,7 @@ class AxisItem(GraphicsWidget):
|
||||
## draw ticks
|
||||
## (to improve performance, we do not interleave line and text drawing, since this causes unnecessary pipeline switching)
|
||||
## draw three different intervals, long ticks first
|
||||
|
||||
for i in range(len(tickLevels)):
|
||||
tickPositions.append([])
|
||||
ticks = tickLevels[i][1]
|
||||
@ -557,7 +562,13 @@ class AxisItem(GraphicsWidget):
|
||||
lineAlpha = self.grid
|
||||
|
||||
for v in ticks:
|
||||
## determine actual position to draw this tick
|
||||
x = (v * xScale) - offset
|
||||
if x < xMin or x > xMax: ## last check to make sure no out-of-bounds ticks are drawn
|
||||
tickPositions[i].append(None)
|
||||
continue
|
||||
tickPositions[i].append(x)
|
||||
|
||||
p1 = [x, x]
|
||||
p2 = [x, x]
|
||||
p1[axis] = tickStart
|
||||
@ -570,7 +581,6 @@ class AxisItem(GraphicsWidget):
|
||||
tickPen.setColor(color)
|
||||
p.setPen(tickPen)
|
||||
p.drawLine(Point(p1), Point(p2))
|
||||
tickPositions[i].append(x)
|
||||
prof.mark('draw ticks')
|
||||
|
||||
## Draw text until there is no more room (or no more text)
|
||||
@ -586,9 +596,14 @@ class AxisItem(GraphicsWidget):
|
||||
if len(strings) == 0:
|
||||
continue
|
||||
|
||||
## ignore strings belonging to ticks that were previously ignored
|
||||
for j in range(len(strings)):
|
||||
if tickPositions[i][j] is None:
|
||||
strings[j] = None
|
||||
|
||||
if i > 0: ## always draw top level
|
||||
## measure all text, make sure there's enough room
|
||||
textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings])
|
||||
textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings if s is not None])
|
||||
if axis == 0:
|
||||
textSize = np.sum([r.height() for r in textRects])
|
||||
else:
|
||||
@ -603,6 +618,8 @@ class AxisItem(GraphicsWidget):
|
||||
#strings = self.tickStrings(values, self.scale, spacing)
|
||||
for j in range(len(strings)):
|
||||
vstr = strings[j]
|
||||
if vstr is None:## this tick was ignored because it is out of bounds
|
||||
continue
|
||||
x = tickPositions[i][j]
|
||||
textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr)
|
||||
height = textRect.height()
|
||||
|
@ -37,7 +37,7 @@ class Parallelize:
|
||||
since it is automatically sent via pipe back to the parent process.
|
||||
"""
|
||||
|
||||
def __init__(self, tasks, workers=None, block=True, progressDialog=None, **kwds):
|
||||
def __init__(self, tasks, workers=None, block=True, progressDialog=None, randomReseed=True, **kwds):
|
||||
"""
|
||||
=============== ===================================================================
|
||||
Arguments:
|
||||
@ -47,6 +47,9 @@ class Parallelize:
|
||||
system
|
||||
progressDialog optional dict of arguments for ProgressDialog
|
||||
to update while tasks are processed
|
||||
randomReseed If True, each forked process will reseed its random number generator
|
||||
to ensure independent results. Works with the built-in random
|
||||
and numpy.random.
|
||||
kwds objects to be shared by proxy with child processes (they will
|
||||
appear as attributes of the tasker)
|
||||
=============== ===================================================================
|
||||
@ -68,6 +71,7 @@ class Parallelize:
|
||||
workers = 1
|
||||
self.workers = workers
|
||||
self.tasks = list(tasks)
|
||||
self.reseed = randomReseed
|
||||
self.kwds = kwds.copy()
|
||||
self.kwds['_taskStarted'] = self._taskStarted
|
||||
|
||||
@ -112,7 +116,7 @@ class Parallelize:
|
||||
|
||||
## fork and assign tasks to each worker
|
||||
for i in range(workers):
|
||||
proc = ForkedProcess(target=None, preProxy=self.kwds)
|
||||
proc = ForkedProcess(target=None, preProxy=self.kwds, randomReseed=self.reseed)
|
||||
if not proc.isParent:
|
||||
self.proc = proc
|
||||
return Tasker(proc, chunks[i], proc.forkedProxies)
|
||||
@ -150,7 +154,17 @@ class Parallelize:
|
||||
#print "remove:", [ch.childPid for ch in rem]
|
||||
for ch in rem:
|
||||
activeChilds.remove(ch)
|
||||
while True:
|
||||
try:
|
||||
os.waitpid(ch.childPid, 0)
|
||||
break
|
||||
except OSError as ex:
|
||||
if ex.errno == 4: ## If we get this error, just try again
|
||||
continue
|
||||
#print "Ignored system call interruption"
|
||||
else:
|
||||
raise
|
||||
|
||||
#print [ch.childPid for ch in activeChilds]
|
||||
|
||||
if self.showProgress and self.progressDlg.wasCanceled():
|
||||
|
Loading…
Reference in New Issue
Block a user