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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
d2ef994b
Commit
d2ef994b
authored
Sep 22, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue error for nogil Py->C conversion & support runtime num_threads
parent
27cb4ad5
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
71 additions
and
11 deletions
+71
-11
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+4
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+3
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+31
-7
tests/errors/e_invalid_num_threads.pyx
tests/errors/e_invalid_num_threads.pyx
+10
-1
tests/run/parallel.pyx
tests/run/parallel.pyx
+21
-0
tests/run/sequential_parallel.pyx
tests/run/sequential_parallel.pyx
+2
-2
No files found.
Cython/Compiler/Code.py
View file @
d2ef994b
...
...
@@ -986,11 +986,13 @@ class CCodeWriter(object):
if
create_from
is
not
None
:
# Use same global state
self
.
globalstate
=
create_from
.
globalstate
self
.
funcstate
=
create_from
.
funcstate
# Clone formatting state
if
copy_formatting
:
self
.
level
=
create_from
.
level
self
.
bol
=
create_from
.
bol
self
.
call_level
=
create_from
.
call_level
if
emit_linenums
is
None
and
self
.
globalstate
:
self
.
emit_linenums
=
self
.
globalstate
.
emit_linenums
else
:
...
...
@@ -1000,7 +1002,8 @@ class CCodeWriter(object):
def
create_new
(
self
,
create_from
,
buffer
,
copy_formatting
):
# polymorphic constructor -- very slightly more versatile
# than using __class__
result
=
CCodeWriter
(
create_from
,
buffer
,
copy_formatting
,
c_line_in_traceback
=
self
.
c_line_in_traceback
)
result
=
CCodeWriter
(
create_from
,
buffer
,
copy_formatting
,
c_line_in_traceback
=
self
.
c_line_in_traceback
)
return
result
def
copyto
(
self
,
f
):
...
...
Cython/Compiler/ExprNodes.py
View file @
d2ef994b
...
...
@@ -7814,6 +7814,9 @@ class CoerceFromPyTypeNode(CoercionNode):
if
self
.
type
.
is_pyobject
:
code
.
put_gotref
(
self
.
py_result
())
def
nogil_check
(
self
,
env
):
error
(
self
.
pos
,
"Coercion from Python not allowed without the GIL"
)
class
CoerceToBooleanNode
(
CoercionNode
):
# This node is used when a result needs to be used
...
...
Cython/Compiler/Nodes.py
View file @
d2ef994b
...
...
@@ -5929,7 +5929,7 @@ class ParallelStatNode(StatNode, ParallelNode):
construct (replaced by its compile time value)
"""
child_attrs
=
[
'body'
]
child_attrs
=
[
'body'
,
'num_threads'
]
body
=
None
...
...
@@ -5937,6 +5937,8 @@ class ParallelStatNode(StatNode, ParallelNode):
error_label_used
=
False
num_threads
=
None
parallel_exc
=
(
Naming
.
parallel_exc_type
,
Naming
.
parallel_exc_value
,
...
...
@@ -5977,7 +5979,15 @@ class ParallelStatNode(StatNode, ParallelNode):
def
analyse_declarations
(
self
,
env
):
self
.
body
.
analyse_declarations
(
env
)
self
.
num_threads
=
None
if
self
.
kwargs
:
for
idx
,
dictitem
in
enumerate
(
self
.
kwargs
.
key_value_pairs
[:]):
if
dictitem
.
key
.
value
==
'num_threads'
:
self
.
num_threads
=
dictitem
.
value
del
self
.
kwargs
.
key_value_pairs
[
idx
]
break
try
:
self
.
kwargs
=
self
.
kwargs
.
compile_time_value
(
env
)
except
Exception
,
e
:
...
...
@@ -5993,6 +6003,8 @@ class ParallelStatNode(StatNode, ParallelNode):
setattr
(
self
,
kw
,
val
)
def
analyse_expressions
(
self
,
env
):
if
self
.
num_threads
:
self
.
num_threads
.
analyse_expressions
(
env
)
self
.
body
.
analyse_expressions
(
env
)
self
.
analyse_sharing_attributes
(
env
)
...
...
@@ -6000,13 +6012,18 @@ class ParallelStatNode(StatNode, ParallelNode):
if
self
.
parent
and
self
.
parent
.
num_threads
is
not
None
:
error
(
self
.
pos
,
"num_threads already declared in outer section"
)
elif
not
isinstance
(
self
.
num_threads
,
(
int
,
long
))
:
elif
self
.
parent
:
error
(
self
.
pos
,
"Invalid value for num_threads argument, expected an int"
)
elif
self
.
num_threads
<=
0
:
"num_threads must be declared in the parent parallel section"
)
elif
(
self
.
num_threads
.
type
.
is_int
and
self
.
num_threads
.
is_literal
and
self
.
num_threads
.
compile_time_value
(
env
)
<=
0
):
error
(
self
.
pos
,
"argument to num_threads must be greater than 0"
)
self
.
num_threads
=
self
.
num_threads
.
coerce_to
(
PyrexTypes
.
c_int_type
,
env
).
coerce_to_temp
(
env
)
def
analyse_sharing_attributes
(
self
,
env
):
"""
Analyse the privates for this block and set them in self.privates.
...
...
@@ -6146,7 +6163,16 @@ class ParallelStatNode(StatNode, ParallelNode):
Write self.num_threads if set as the num_threads OpenMP directive
"""
if
self
.
num_threads
is
not
None
:
code
.
put
(
" num_threads(%d)"
%
(
self
.
num_threads
,))
c
=
self
.
begin_of_parallel_control_block_point
# we need to set the owner to ourselves temporarily, as
# allocate_temp may generate a comment in the middle of our pragma
# otherwise when DebugFlags.debug_temp_code_comments is in effect
owner
=
c
.
funcstate
.
owner
c
.
funcstate
.
owner
=
c
self
.
num_threads
.
generate_evaluation_code
(
c
)
c
.
funcstate
.
owner
=
owner
code
.
put
(
" num_threads(%s)"
%
(
self
.
num_threads
.
result
(),))
def
declare_closure_privates
(
self
,
code
):
...
...
@@ -6511,8 +6537,6 @@ class ParallelWithBlockNode(ParallelStatNode):
This node represents a 'with cython.parallel.parallel():' block
"""
nogil_check
=
None
valid_keyword_arguments
=
[
'num_threads'
]
num_threads
=
None
...
...
tests/errors/e_invalid_num_threads.pyx
View file @
d2ef994b
...
...
@@ -19,8 +19,17 @@ with nogil, parallel(num_threads=2):
for
i
in
prange
(
10
,
num_threads
=
2
):
pass
with
nogil
,
parallel
():
for
i
in
prange
(
10
,
num_threads
=
2
):
pass
# this one is valid
for
i
in
prange
(
10
,
nogil
=
True
,
num_threads
=
2
):
pass
_ERRORS
=
u"""
e_invalid_num_threads.pyx:8:33: Coercion from Python not allowed without the GIL
e_invalid_num_threads.pyx:12:20: argument to num_threads must be greater than 0
e_invalid_num_threads.pyx:15:20: Invalid value for num_threads argument, expected an int
e_invalid_num_threads.pyx:19:19: num_threads already declared in outer section
e_invalid_num_threads.pyx:23:19: num_threads must be declared in the parent parallel section
"""
tests/run/parallel.pyx
View file @
d2ef994b
...
...
@@ -26,10 +26,18 @@ def test_parallel():
free
(
buf
)
cdef
int
get_num_threads
()
with
gil
:
print
"get_num_threads called"
return
3
def
test_num_threads
():
"""
>>> test_num_threads()
1
get_num_threads called
3
get_num_threads called
3
"""
cdef
int
dyn
=
openmp
.
omp_get_dynamic
()
cdef
int
num_threads
...
...
@@ -40,6 +48,19 @@ def test_num_threads():
with
nogil
,
cython
.
parallel
.
parallel
(
num_threads
=
1
):
p
[
0
]
=
openmp
.
omp_get_num_threads
()
print
num_threads
with
nogil
,
cython
.
parallel
.
parallel
(
num_threads
=
get_num_threads
()):
p
[
0
]
=
openmp
.
omp_get_num_threads
()
print
num_threads
cdef
int
i
num_threads
=
0xbad
for
i
in
prange
(
1
,
nogil
=
True
,
num_threads
=
get_num_threads
()):
p
[
0
]
=
openmp
.
omp_get_num_threads
()
break
openmp
.
omp_set_dynamic
(
dyn
)
return
num_threads
...
...
tests/run/sequential_parallel.pyx
View file @
d2ef994b
...
...
@@ -729,6 +729,6 @@ def test_num_threads_compile():
with
nogil
,
cython
.
parallel
.
parallel
(
num_threads
=
2
):
pass
with
nogil
,
cython
.
parallel
.
parallel
():
for
i
in
prange
(
10
,
num_threads
=
2
):
with
nogil
,
cython
.
parallel
.
parallel
(
num_threads
=
2
):
for
i
in
prange
(
10
):
pass
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