Commit 3a446eee authored by Mark Florisson's avatar Mark Florisson

Disallow object reductions + support CF

parent b8a6081e
...@@ -820,6 +820,13 @@ class CreateControlFlowGraph(CythonTransform): ...@@ -820,6 +820,13 @@ class CreateControlFlowGraph(CythonTransform):
self.flow.block = None self.flow.block = None
return node return node
def visit_ParallelRangeNode(self, node):
# if node.target is None an error will have been previously issued
if node.target is not None:
node = self.visit_ForInStatNode(node)
return node
def visit_ForFromStatNode(self, node): def visit_ForFromStatNode(self, node):
condition_block = self.flow.nextblock() condition_block = self.flow.nextblock()
next_block = self.flow.newblock() next_block = self.flow.newblock()
......
...@@ -5977,7 +5977,7 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -5977,7 +5977,7 @@ class ParallelStatNode(StatNode, ParallelNode):
if entry.cname in self.seen_closure_vars: if entry.cname in self.seen_closure_vars:
return entry.cname return entry.cname
cname = code.funcstate.allocate_temp(entry.type, False) cname = code.funcstate.allocate_temp(entry.type, True)
# Add both the actual cname and the temp cname, as the actual cname # Add both the actual cname and the temp cname, as the actual cname
# will be replaced with the temp cname on the entry # will be replaced with the temp cname on the entry
...@@ -6297,6 +6297,11 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -6297,6 +6297,11 @@ class ParallelRangeNode(ParallelStatNode):
valid_keyword_arguments = ['schedule', 'nogil', 'num_threads'] valid_keyword_arguments = ['schedule', 'nogil', 'num_threads']
def __init__(self, pos, **kwds):
super(ParallelRangeNode, self).__init__(pos, **kwds)
# Pretend to be a ForInStatNode for control flow analysis
self.iterator = PassStatNode(pos)
def analyse_declarations(self, env): def analyse_declarations(self, env):
super(ParallelRangeNode, self).analyse_declarations(env) super(ParallelRangeNode, self).analyse_declarations(env)
self.target.analyse_target_declaration(env) self.target.analyse_target_declaration(env)
...@@ -6512,7 +6517,10 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -6512,7 +6517,10 @@ class ParallelRangeNode(ParallelStatNode):
for entry, op in self.privates.iteritems(): for entry, op in self.privates.iteritems():
# Don't declare the index variable as a reduction # Don't declare the index variable as a reduction
if op and op in "+*-&^|" and entry != self.target.entry: if op and op in "+*-&^|" and entry != self.target.entry:
code.put(" reduction(%s:%s)" % (op, entry.cname)) if entry.type.is_pyobject:
error(self.pos, "Python objects cannot be reductions")
else:
code.put(" reduction(%s:%s)" % (op, entry.cname))
else: else:
if entry == self.target.entry: if entry == self.target.entry:
code.put(" firstprivate(%s)" % entry.cname) code.put(" firstprivate(%s)" % entry.cname)
......
# mode: error
from cython.parallel cimport prange
def invalid_closure_reduction():
sum = 0
def inner():
nonlocal sum
cdef int i
for i in prange(10, nogil=True):
with gil:
sum += i
_ERRORS = u"""
e_cython_parallel_pyobject_reduction.pyx:10:23: Python objects cannot be reductions
"""
...@@ -147,6 +147,31 @@ def test_closure_parallel_privates(): ...@@ -147,6 +147,31 @@ def test_closure_parallel_privates():
g = test_generator() g = test_generator()
print next(g), x, next(g), x print next(g), x, next(g), x
def test_closure_parallel_with_gil():
"""
>>> test_closure_parallel_with_gil()
45
45
"""
cdef int sum = 0
temp1 = 5
temp2 = -5
def test_reduction():
nonlocal sum, temp1, temp2
cdef int i
for i in prange(10, nogil=True):
with gil:
sum += temp1 + temp2 + i
assert abs(sum - sum) == 0
return sum
print test_reduction()
print sum
def test_pure_mode(): def test_pure_mode():
""" """
>>> test_pure_mode() >>> test_pure_mode()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment