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