Commit b982881e authored by Stefan Behnel's avatar Stefan Behnel

merge

parents a068e66f cf2290aa
......@@ -5783,7 +5783,7 @@ class ParallelNode(Node):
class ParallelStatNode(StatNode, ParallelNode):
"""
Base class for 'with cython.parallel.parallel:' and 'for i in prange():'.
Base class for 'with cython.parallel.parallel():' and 'for i in prange():'.
assignments { Entry(var) : (var.pos, inplace_operator_or_None) }
assignments to variables in this parallel section
......@@ -5967,7 +5967,7 @@ class ParallelStatNode(StatNode, ParallelNode):
class ParallelWithBlockNode(ParallelStatNode):
"""
This node represents a 'with cython.parallel.parallel:' block
This node represents a 'with cython.parallel.parallel():' block
"""
nogil_check = None
......
......@@ -665,16 +665,20 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
PyrexTypes.parse_basic_type(name))
def is_parallel_directive(self, full_name, pos):
"""
Checks to see if fullname (e.g. cython.parallel.prange) is a valid
parallel directive. If it is a star import it also updates the
parallel_directives.
"""
result = (full_name + ".").startswith("cython.parallel.")
if result:
directive = full_name.rsplit('.', 1)
if len(directive) == 2 and directive[1] == '*':
# star import
directive = full_name.split('.')
if full_name == u"cython.parallel.*":
for name in self.valid_parallel_directives:
self.parallel_directives[name] = u"cython.parallel.%s" % name
elif (len(directive) != 2 or
directive[1] not in self.valid_parallel_directives):
elif (len(directive) != 3 or
directive[-1] not in self.valid_parallel_directives):
error(pos, "No such directive: %s" % full_name)
return result
......@@ -959,7 +963,7 @@ class ParallelRangeTransform(CythonTransform, SkipDeclarations):
module node, set there by InterpretCompilerDirectives.
x = cython.parallel.threadavailable() -> ParallelThreadAvailableNode
with nogil, cython.parallel.parallel: -> ParallelWithBlockNode
with nogil, cython.parallel.parallel(): -> ParallelWithBlockNode
print cython.parallel.threadid() -> ParallelThreadIdNode
for i in cython.parallel.prange(...): -> ParallelRangeNode
...
......@@ -1060,36 +1064,40 @@ class ParallelRangeTransform(CythonTransform, SkipDeclarations):
parallel_directive_class = self.get_directive_class_node(node)
if parallel_directive_class:
# Note: in case of a parallel() the body is set by
# visit_WithStatNode
node = parallel_directive_class(node.pos, args=args, kwargs=kwargs)
return node
def visit_WithStatNode(self, node):
"Rewrite with cython.parallel() blocks"
self.visit(node.manager)
if self.parallel_directive:
parallel_directive_class = self.get_directive_class_node(node)
if not parallel_directive_class:
# There was an error, stop here and now
return None
"Rewrite with cython.parallel.parallel() blocks"
newnode = self.visit(node.manager)
if isinstance(newnode, Nodes.ParallelWithBlockNode):
if self.state == 'parallel with':
error(node.manager.pos,
"Closely nested 'with parallel:' blocks are disallowed")
self.state = 'parallel with'
self.visit(node.body)
body = self.visit(node.body)
self.state = None
newnode = Nodes.ParallelWithBlockNode(node.pos, body=node.body)
newnode.body = body
return newnode
elif self.parallel_directive:
parallel_directive_class = self.get_directive_class_node(node)
else:
newnode = node
if not parallel_directive_class:
# There was an error, stop here and now
return None
self.visit(node.body)
if parallel_directive_class is Nodes.ParallelWithBlockNode:
error(node.pos, "The parallel directive must be called")
return None
return newnode
node.body = self.visit(node.body)
return node
def visit_ForInStatNode(self, node):
"Rewrite 'for i in cython.parallel.prange(...):'"
......@@ -1145,7 +1153,7 @@ class ParallelRangeTransform(CythonTransform, SkipDeclarations):
def visit(self, node):
"Visit a node that may be None"
if node is not None:
super(ParallelRangeTransform, self).visit(node)
return super(ParallelRangeTransform, self).visit(node)
class WithTransform(CythonTransform, SkipDeclarations):
......
......@@ -118,7 +118,7 @@ def get_openmp_compiler_flags(language):
import subprocess
except ImportError:
try:
in_, out, err = os.popen(cc + " -v")
in_, out_err = os.popen4([cc, "-v"])
except EnvironmentError:
# Be compatible with Python 3
_, e, _ = sys.exc_info()
......@@ -126,7 +126,7 @@ def get_openmp_compiler_flags(language):
(language, os.strerror(e.errno), cc))
return None
output = out.read() or err.read()
output = out_err.read()
else:
try:
p = subprocess.Popen([cc, "-v"], stdout=subprocess.PIPE,
......
......@@ -14,16 +14,16 @@ prange(1, 2, 3, schedule='dynamic')
cdef int i
with nogil, cython.parallel.parallel:
with nogil, cython.parallel.parallel():
for i in prange(10, schedule='invalid_schedule'):
pass
with cython.parallel.parallel:
with cython.parallel.parallel():
print "hello world!"
cdef int *x = NULL
with nogil, cython.parallel.parallel:
with nogil, cython.parallel.parallel():
for j in prange(10):
pass
......@@ -33,7 +33,10 @@ with nogil, cython.parallel.parallel:
for x in prange(10):
pass
with cython.parallel.parallel:
with cython.parallel.parallel():
pass
with nogil, cython.parallel.parallel:
pass
_ERRORS = u"""
......@@ -44,9 +47,10 @@ e_cython_parallel.pyx:7:0: No such directive: cython.parallel.something
e_cython_parallel.pyx:13:6: prange() can only be used as part of a for loop
e_cython_parallel.pyx:13:6: prange() can only be used without the GIL
e_cython_parallel.pyx:18:19: Invalid schedule argument to prange: invalid_schedule
e_cython_parallel.pyx:21:5: The parallel section may only be used without the GIL
c_cython_parallel.pyx:21:29: The parallel section may only be used without the GIL
e_cython_parallel.pyx:27:10: target may not be a Python object as we don't have the GIL
e_cython_parallel.pyx:30:9: Can only iterate over an iteration variable
e_cython_parallel.pyx:33:10: Must be of numeric type, not int *
e_cython_parallel.pyx:36:24: Closely nested 'with parallel:' blocks are disallowed
e_cython_parallel.pyx:36:33: Closely nested 'with parallel:' blocks are disallowed
e_cython_parallel.pyx:39:12: The parallel directive must be called
"""
......@@ -16,7 +16,7 @@ def test_parallel():
if buf == NULL:
raise MemoryError
with nogil, cython.parallel.parallel:
with nogil, cython.parallel.parallel():
buf[threadid()] = threadid()
for i in range(maxthreads):
......@@ -24,4 +24,4 @@ def test_parallel():
free(buf)
include "sequential_parallel.pyx"
#include "sequential_parallel.pyx"
......@@ -23,7 +23,7 @@ def test_prange():
"""
cdef Py_ssize_t i, j, sum1 = 0, sum2 = 0
with nogil, cython.parallel.parallel:
with nogil, cython.parallel.parallel():
for i in prange(10, schedule='dynamic'):
sum1 += i
......@@ -57,9 +57,9 @@ def test_propagation():
for j in prange(10):
sum1 += i
with nogil, cython.parallel.parallel:
with nogil, cython.parallel.parallel():
for x in prange(10):
with cython.parallel.parallel:
with cython.parallel.parallel():
for y in prange(10):
sum2 += y
......
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