Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
2675a89c
Commit
2675a89c
authored
Dec 02, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow nested prange() & less warnings
parent
d532f26a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
63 additions
and
115 deletions
+63
-115
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+32
-5
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+1
-1
Cython/Compiler/TypeInference.py
Cython/Compiler/TypeInference.py
+2
-4
tests/errors/e_cython_parallel.pyx
tests/errors/e_cython_parallel.pyx
+6
-3
tests/run/sequential_parallel.pyx
tests/run/sequential_parallel.pyx
+22
-102
No files found.
Cython/Compiler/Nodes.py
View file @
2675a89c
...
...
@@ -6834,10 +6834,11 @@ class ParallelStatNode(StatNode, ParallelNode):
self
.
analyse_sharing_attributes
(
env
)
if
self
.
num_threads
is
not
None
:
if
self
.
parent
and
self
.
parent
.
num_threads
is
not
None
:
if
(
self
.
parent
and
self
.
parent
.
num_threads
is
not
None
and
not
self
.
parent
.
is_prange
):
error
(
self
.
pos
,
"num_threads already declared in outer section"
)
elif
self
.
parent
:
elif
self
.
parent
and
not
self
.
parent
.
is_prange
:
error
(
self
.
pos
,
"num_threads must be declared in the parent parallel section"
)
elif
(
self
.
num_threads
.
type
.
is_int
and
...
...
@@ -7113,11 +7114,15 @@ class ParallelStatNode(StatNode, ParallelNode):
begin_code
=
self
.
begin_of_parallel_block
end_code
=
code
begin_code
.
putln
(
"#ifdef _OPENMP"
)
begin_code
.
put_ensure_gil
(
declare_gilstate
=
True
)
begin_code
.
putln
(
"Py_BEGIN_ALLOW_THREADS"
)
begin_code
.
putln
(
"#endif /* _OPENMP */"
)
end_code
.
putln
(
"#ifdef _OPENMP"
)
end_code
.
putln
(
"Py_END_ALLOW_THREADS"
)
end_code
.
put_release_ensured_gil
()
end_code
.
putln
(
"#endif /* _OPENMP */"
)
def
trap_parallel_exit
(
self
,
code
,
should_flush
=
False
):
"""
...
...
@@ -7216,8 +7221,13 @@ class ParallelStatNode(StatNode, ParallelNode):
temp_count
+=
1
invalid_value
=
entry
.
type
.
invalid_value
()
if
invalid_value
:
init
=
' = '
+
invalid_value
else
:
init
=
''
# Declare the parallel private in the outer block
c
.
putln
(
"%s %s
;"
%
(
type_decl
,
temp_cname
))
c
.
putln
(
"%s %s
%s;"
%
(
type_decl
,
temp_cname
,
init
))
# Initialize before escaping
code
.
putln
(
"%s = %s;"
%
(
temp_cname
,
private_cname
))
...
...
@@ -7434,6 +7444,7 @@ class ParallelRangeNode(ParallelStatNode):
start
=
stop
=
step
=
None
is_prange
=
True
is_nested_prange
=
False
nogil
=
None
schedule
=
None
...
...
@@ -7544,6 +7555,16 @@ class ParallelRangeNode(ParallelStatNode):
if
self
.
nogil
:
env
.
nogil
=
was_nogil
self
.
is_nested_prange
=
self
.
parent
and
self
.
parent
.
is_prange
if
self
.
is_nested_prange
:
parent
=
self
while
parent
.
parent
and
parent
.
parent
.
is_prange
:
parent
=
parent
.
parent
parent
.
assignments
.
update
(
self
.
assignments
)
parent
.
privates
.
update
(
self
.
privates
)
parent
.
assigned_nodes
.
extend
(
self
.
assigned_nodes
)
def
nogil_check
(
self
,
env
):
names
=
'start'
,
'stop'
,
'step'
,
'target'
nodes
=
self
.
start
,
self
.
stop
,
self
.
step
,
self
.
target
...
...
@@ -7670,7 +7691,10 @@ class ParallelRangeNode(ParallelStatNode):
self
.
release_closure_privates
(
code
)
def
generate_loop
(
self
,
code
,
fmt_dict
):
code
.
putln
(
"#ifdef _OPENMP"
)
if
self
.
is_nested_prange
:
code
.
putln
(
"#if 0"
)
else
:
code
.
putln
(
"#ifdef _OPENMP"
)
if
not
self
.
is_parallel
:
code
.
put
(
"#pragma omp for"
)
...
...
@@ -7688,7 +7712,10 @@ class ParallelRangeNode(ParallelStatNode):
# Initialize the GIL if needed for this thread
self
.
begin_parallel_block
(
code
)
code
.
putln
(
"#ifdef _OPENMP"
)
if
self
.
is_nested_prange
:
code
.
putln
(
"#if 0"
)
else
:
code
.
putln
(
"#ifdef _OPENMP"
)
code
.
put
(
"#pragma omp for"
)
for
entry
,
(
op
,
lastprivate
)
in
self
.
privates
.
iteritems
():
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
2675a89c
...
...
@@ -1099,7 +1099,7 @@ class ParallelRangeTransform(CythonTransform, SkipDeclarations):
if
isinstance
(
newnode
,
Nodes
.
ParallelWithBlockNode
):
if
self
.
state
==
'parallel with'
:
error
(
node
.
manager
.
pos
,
"
Closely n
ested parallel with blocks are disallowed"
)
"
N
ested parallel with blocks are disallowed"
)
self
.
state
=
'parallel with'
body
=
self
.
visit
(
node
.
body
)
...
...
Cython/Compiler/TypeInference.py
View file @
2675a89c
...
...
@@ -196,10 +196,8 @@ class MarkAssignments(CythonTransform):
self
.
parallel_block_stack
.
append
(
node
)
nested
=
nested
or
len
(
self
.
parallel_block_stack
)
>
2
if
not
self
.
parallel_errors
and
nested
:
error
(
node
.
pos
,
"Parallel nesting not supported due to bugs in gcc 4.5"
)
if
not
self
.
parallel_errors
and
nested
and
not
node
.
is_prange
:
error
(
node
.
pos
,
"Only prange() may be nested"
)
self
.
parallel_errors
=
True
if
node
.
is_prange
:
...
...
tests/errors/e_cython_parallel.pyx
View file @
2675a89c
...
...
@@ -145,6 +145,10 @@ cdef int chunksize():
for
i
in
prange
(
10
,
nogil
=
True
,
schedule
=
'static'
,
chunksize
=
chunksize
()):
pass
with
nogil
,
cython
.
parallel
.
parallel
():
with
cython
.
parallel
.
parallel
():
pass
_ERRORS
=
u"""
e_cython_parallel.pyx:3:8: cython.parallel.parallel is not a module
e_cython_parallel.pyx:4:0: No such directive: cython.parallel.something
...
...
@@ -157,7 +161,7 @@ c_cython_parallel.pyx:21:29: The parallel section may only be used without the G
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:33:
Closely n
ested parallel with blocks are disallowed
e_cython_parallel.pyx:36:33:
N
ested parallel with blocks are disallowed
e_cython_parallel.pyx:39:12: The parallel directive must be called
e_cython_parallel.pyx:45:10: local variable 'y' referenced before assignment
e_cython_parallel.pyx:55:9: local variable 'y' referenced before assignment
...
...
@@ -166,8 +170,6 @@ e_cython_parallel.pyx:62:36: cython.parallel.parallel() does not take positional
e_cython_parallel.pyx:65:36: Invalid keyword argument: invalid
e_cython_parallel.pyx:73:12: Yield not allowed in parallel sections
e_cython_parallel.pyx:77:16: Yield not allowed in parallel sections
e_cython_parallel.pyx:82:19: Parallel nesting not supported due to bugs in gcc 4.5
e_cython_parallel.pyx:87:23: Parallel nesting not supported due to bugs in gcc 4.5
e_cython_parallel.pyx:97:19: Cannot assign to private of outer parallel block
e_cython_parallel.pyx:98:19: Cannot assign to private of outer parallel block
e_cython_parallel.pyx:104:6: Reductions not allowed for parallel blocks
...
...
@@ -180,4 +182,5 @@ e_cython_parallel.pyx:133:42: Must provide schedule with chunksize
e_cython_parallel.pyx:136:62: Chunksize must not be negative
e_cython_parallel.pyx:139:62: Chunksize not valid for the schedule runtime
e_cython_parallel.pyx:145:70: Calling gil-requiring function not allowed without gil
e_cython_parallel.pyx:149:33: Nested parallel with blocks are disallowed
"""
tests/run/sequential_parallel.pyx
View file @
2675a89c
...
...
@@ -46,7 +46,6 @@ def test_descending_prange():
return
sum
'''
def
test_propagation
():
"""
>>> test_propagation()
...
...
@@ -61,12 +60,10 @@ def test_propagation():
with
nogil
,
cython
.
parallel
.
parallel
():
for
x
in
prange
(
10
):
with cython.parallel.parallel():
for y in prange(10):
sum2 += y
for
y
in
prange
(
10
):
sum2
+=
y
return
i
,
j
,
x
,
y
,
sum1
,
sum2
'''
def
test_unsigned_operands
():
"""
...
...
@@ -349,7 +346,6 @@ def test_prange_continue():
free
(
p
)
'''
def
test_nested_break_continue
():
"""
>>> test_nested_break_continue()
...
...
@@ -371,16 +367,14 @@ def test_nested_break_continue():
print
i
,
j
,
result1
,
result2
with nogil, cython.parallel.parallel():
for i in prange(10, num_threads=2, schedule='static'):
with cython.parallel.parallel():
if i == 8:
break
else:
continue
with
nogil
,
cython
.
parallel
.
parallel
(
num_threads
=
2
):
for
i
in
prange
(
10
,
schedule
=
'static'
):
if
i
==
8
:
break
else
:
continue
print
i
'''
cdef
int
parallel_return
()
nogil
:
cdef
int
i
...
...
@@ -400,11 +394,10 @@ def test_return():
"""
print
parallel_return
()
'''
def
test_parallel_exceptions
():
"""
>>> test_parallel_exceptions()
('I am executed first', 0)
I am executed first
('propagate me',) 0
"""
cdef
int
i
,
j
,
sum
=
0
...
...
@@ -422,11 +415,10 @@ def test_parallel_exceptions():
sum
+=
i
finally
:
with
gil
:
mylist.append(
("I am executed first", sum)
)
mylist
.
append
(
"I am executed first"
)
except
Exception
,
e
:
print
mylist
[
0
]
print
e
.
args
,
sum
'''
def
test_parallel_exceptions_unnested
():
"""
...
...
@@ -453,7 +445,6 @@ def test_parallel_exceptions_unnested():
print
mylist
[
0
]
print
e
.
args
,
sum
'''
cdef
int
parallel_exc_cdef
()
except
-
3
:
cdef
int
i
,
j
for
i
in
prange
(
10
,
nogil
=
True
):
...
...
@@ -462,7 +453,6 @@ cdef int parallel_exc_cdef() except -3:
raise
Exception
(
"propagate me"
)
return
0
'''
cdef
int
parallel_exc_cdef_unnested
()
except
-
3
:
cdef
int
i
...
...
@@ -480,9 +470,8 @@ def test_parallel_exc_cdef():
Exception: propagate me
"""
parallel_exc_cdef_unnested
()
#
parallel_exc_cdef()
parallel_exc_cdef
()
'''
cpdef
int
parallel_exc_cpdef
()
except
-
3
:
cdef
int
i
,
j
for
i
in
prange
(
10
,
nogil
=
True
):
...
...
@@ -491,7 +480,6 @@ cpdef int parallel_exc_cpdef() except -3:
raise
Exception
(
"propagate me"
)
return
0
'''
cpdef
int
parallel_exc_cpdef_unnested
()
except
-
3
:
cdef
int
i
,
j
...
...
@@ -510,9 +498,8 @@ def test_parallel_exc_cpdef():
Exception: propagate me
"""
parallel_exc_cpdef_unnested
()
#
parallel_exc_cpdef()
parallel_exc_cpdef
()
'''
cdef
int
parallel_exc_nogil_swallow
()
except
-
1
:
cdef
int
i
,
j
for
i
in
prange
(
10
,
nogil
=
True
):
...
...
@@ -524,7 +511,6 @@ cdef int parallel_exc_nogil_swallow() except -1:
return
i
return
0
'''
cdef
int
parallel_exc_nogil_swallow_unnested
()
except
-
1
:
cdef
int
i
...
...
@@ -542,13 +528,13 @@ def test_parallel_exc_nogil_swallow():
"""
>>> test_parallel_exc_nogil_swallow()
execute me
execute me
"""
parallel_exc_nogil_swallow_unnested
()
print
'execute me'
#
parallel_exc_nogil_swallow()
#
print 'execute me'
parallel_exc_nogil_swallow
()
print
'execute me'
'''
def
parallel_exc_replace
():
"""
>>> parallel_exc_replace()
...
...
@@ -569,7 +555,13 @@ def parallel_exc_replace():
return
0
def _parallel_exceptions2():
def
parallel_exceptions2
():
"""
>>> parallel_exceptions2()
Traceback (most recent call last):
...
Exception: propagate me
"""
cdef
int
i
,
j
,
k
for
i
in
prange
(
10
,
nogil
=
True
):
...
...
@@ -582,59 +574,6 @@ def _parallel_exceptions2():
continue
return
def test_parallel_exceptions2():
"""
DISABLED
test_parallel_exceptions2()
read: start
propagate me
exiting...
Exit status: 0
"""
if not hasattr(os, 'fork'):
print 'start'
print 'propagate me'
print 'Exit status: 0'
return
r, w = os.pipe()
fr = os.fdopen(r, 'r')
fw = os.fdopen(w, 'w', 0)
pid = os.fork()
if pid == 0:
try:
fr.close()
os.dup2(w, 1)
os.dup2(w, 2)
print >>fw, 'start'
try:
_parallel_exceptions2()
except Exception, e:
print >>fw, e.args[0]
else:
print >>fw, 'No exception caught'
except:
import traceback
print >>fw, traceback.format_exc()
finally:
print >>fw, 'exiting...'
os._exit(0)
else:
fw.close()
print 'read:', fr.read(),
pid, status = os.waitpid(pid, 0)
if os.WIFSIGNALED(status):
print 'Got signal', os.WTERMSIG(status)
print 'Exit status:', os.WEXITSTATUS(status)
'''
def
test_parallel_with_gil_return
():
"""
>>> test_parallel_with_gil_return()
...
...
@@ -654,25 +593,6 @@ def test_parallel_with_gil_return():
with
gil
:
return
sum
'''
def test_parallel_with_gil_continue():
"""
>>> test_parallel_with_gil_continue()
20
"""
cdef int i, sum = 0
for i in prange(10, nogil=True):
with cython.parallel.parallel():
with gil:
if i % 2:
continue
sum += i
print sum
'''
def
test_parallel_with_gil_continue_unnested
():
"""
>>> test_parallel_with_gil_continue_unnested()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment