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
6989e004
Commit
6989e004
authored
May 05, 2011
by
Mark Florisson
Committed by
Dag Sverre Seljebotn
May 25, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initiliaze private variables to maximum values or NaNs
parent
4a11afa6
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
156 additions
and
6 deletions
+156
-6
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+58
-4
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+5
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+18
-0
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+25
-0
Cython/Shadow.py
Cython/Shadow.py
+2
-1
tests/run/sequential_parallel.pyx
tests/run/sequential_parallel.pyx
+48
-1
No files found.
Cython/Compiler/ModuleNode.py
View file @
6989e004
...
...
@@ -499,8 +499,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#define DL_EXPORT(t) t
#endif
#ifndef PY_LONG_LONG
#ifdef PY_LONG_LONG
#define %(LONG_LONG_MAX)s PY_LLONG_MAX
#define %(ULONG_LONG_MAX)s PY_ULLONG_MAX
#else
#define PY_LONG_LONG LONG_LONG
#if defined(LLONG_MAX)
#define %(LONG_LONG_MAX)s LLONG_MAX
#define %(ULONG_LONG_MAX)s ULLONG_MAX
#else
#define %(LONG_LONG_MAX)s LONG_MAX
#define %(ULONG_LONG_MAX)s ULONG_MAX
#endif
#endif
#if PY_VERSION_HEX < 0x02040000
...
...
@@ -637,7 +648,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
#endif
"""
)
"""
%
vars
(
Naming
)
)
code
.
put
(
"""
#if PY_MAJOR_VERSION >= 3
...
...
@@ -699,10 +710,52 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
""
)
self
.
generate_extern_c_macro_definition
(
code
)
code
.
putln
(
""
)
code
.
putln
(
"#if defined(WIN32) || defined(MS_WINDOWS)"
)
code
.
putln
(
"#define _USE_MATH_DEFINES"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"""
/* Define NAN */
#ifdef Py_NAN
#include <math.h>
#define %(pyx_nan)s Py_NAN
#else
#if defined(__GNUC__)
#define _GNU_SOURCE
#endif
#include <math.h>
#ifdef NAN
#define %(pyx_nan)s NAN
#else
#if defined(HUGE_VALL)
#define %(pyx_nan)s HUGE_VALL
#elif defined(__STDC__) && __STDC_VERSION__ >= 199901L
/* C99 or greater */
#include <float.h>
#define %(pyx_nan)s LDBL_MAX
#else
static PY_LONG_LONG __pyx__nan = PY_LLONG_MAX;
#define %(pyx_nan)s (*(double*) &__pyx__nan)
#endif
#endif
#endif
#ifdef PY_LONG_LONG
#define __PYX_LONG_LONG_MAX PY_LLONG_MAX
#define __PYX_ULONG_LONG_MAX PY_ULLONG_MAX
#elif defined(LLONG_MAX)
#define __PYX_LONG_LONG_MAX LLONG_MAX
#define __PYX_ULONG_LONG_MAX ULLONG_MAX
#else
/* This should probably suffice, even if not strictly the largest value */
#define __PYX_LONG_LONG_MAX LONG_MAX
#define __PYX_ULONG_LONG_MAX ULONG_MAX
#endif
"""
%
{
'pyx_nan'
:
Naming
.
NAN
})
code
.
putln
(
"#define %s"
%
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
...
...
@@ -711,6 +764,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#define CYTHON_WITHOUT_ASSERTIONS"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
""
)
if
env
.
directives
[
'ccomplex'
]:
code
.
putln
(
""
)
code
.
putln
(
"#if !defined(CYTHON_CCOMPLEX)"
)
...
...
Cython/Compiler/Naming.py
View file @
6989e004
...
...
@@ -116,5 +116,10 @@ h_guard_prefix = "__PYX_HAVE__"
api_guard_prefix
=
"__PYX_HAVE_API__"
api_func_guard
=
"__PYX_HAVE_API_FUNC_"
NAN
=
"__PYX_NAN"
HUGE_VAL
=
"Py_HUGE_VAL"
LONG_LONG_MAX
=
"__PYX_LONG_LONG_MAX"
ULONG_LONG_MAX
=
"__PYX_ULONG_LONG_MAX"
def
py_version_hex
(
major
,
minor
=
0
,
micro
=
0
,
release_level
=
0
,
release_serial
=
0
):
return
(
major
<<
24
)
|
(
minor
<<
16
)
|
(
micro
<<
8
)
|
(
release_level
<<
4
)
|
(
release_serial
)
Cython/Compiler/Nodes.py
View file @
6989e004
...
...
@@ -6007,6 +6007,9 @@ class ParallelStatNode(StatNode, ParallelNode):
for i in prange(10, nogil=True):
var = x # error, x is private and read before assigned
x = i
Fortunately, it doesn't need to be perfect, as we still initialize
private variables to maximum values, NULL or NaN whenever possible.
"""
from
Cython.Compiler
import
ParseTreeTransforms
...
...
@@ -6022,6 +6025,17 @@ class ParallelStatNode(StatNode, ParallelNode):
if
not
op
and
pos
<
assignment_pos
:
error
(
pos
,
"Private variable referenced before assignment"
)
def
initialize_privates_to_nan
(
self
,
code
,
exclude
=
None
):
code
.
putln
(
"/* Initialize private variables to invalid values */"
)
for
entry
,
op
in
self
.
privates
.
iteritems
():
if
not
op
and
(
not
exclude
or
entry
!=
exclude
):
max_value
=
entry
.
type
.
max_value
()
if
max_value
:
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
entry
.
type
.
cast_code
(
max_value
)))
def
declare_closure_privates
(
self
,
code
):
"""
Set self.privates to a dict mapping C variable names that are to be
...
...
@@ -6075,6 +6089,7 @@ class ParallelWithBlockNode(ParallelStatNode):
code
.
putln
(
"#endif /* _OPENMP */"
)
code
.
begin_block
()
self
.
initialize_privates_to_nan
(
code
)
self
.
body
.
generate_execution_code
(
code
)
code
.
end_block
()
...
...
@@ -6334,6 +6349,9 @@ class ParallelRangeNode(ParallelStatNode):
code
.
put
(
"for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)"
%
fmt_dict
)
code
.
begin_block
()
code
.
putln
(
"%(target)s = %(start)s + %(step)s * %(i)s;"
%
fmt_dict
)
self
.
initialize_privates_to_nan
(
code
,
exclude
=
self
.
target
.
entry
)
self
.
body
.
generate_execution_code
(
code
)
code
.
end_block
()
...
...
Cython/Compiler/PyrexTypes.py
View file @
6989e004
...
...
@@ -27,6 +27,12 @@ class BaseType(object):
else
:
return
base_code
def
max_value
(
self
):
"""
Returns the maximum or most invalid value an object of this type can
assume as a C expression string. Returns None if no such value exists.
"""
class
PyrexType
(
BaseType
):
#
# Base class for all Pyrex types.
...
...
@@ -378,6 +384,10 @@ class PyObjectType(PyrexType):
else
:
return
cname
def
max_value
(
self
):
return
"NULL"
class
BuiltinObjectType
(
PyObjectType
):
# objstruct_cname string Name of PyObject struct
...
...
@@ -902,6 +912,8 @@ class CIntType(CNumericType):
def
assignable_from_resolved_type
(
self
,
src_type
):
return
src_type
.
is_int
or
src_type
.
is_enum
or
src_type
is
error_type
def
max_value
(
self
):
return
typename_to_maxval
[
rank_to_type_name
[
self
.
rank
]][
not
self
.
signed
]
class
CAnonEnumType
(
CIntType
):
...
...
@@ -1109,6 +1121,8 @@ class CFloatType(CNumericType):
def
assignable_from_resolved_type
(
self
,
src_type
):
return
(
src_type
.
is_numeric
and
not
src_type
.
is_complex
)
or
src_type
is
error_type
def
max_value
(
self
):
return
Naming
.
NAN
class
CComplexType
(
CNumericType
):
...
...
@@ -1622,6 +1636,8 @@ class CPtrType(CType):
else
:
return
CPtrType
(
base_type
)
def
max_value
(
self
):
return
"NULL"
class
CNullPtrType
(
CPtrType
):
...
...
@@ -2353,6 +2369,15 @@ rank_to_type_name = (
"long double"
,
# 7
)
typename_to_maxval
=
{
"char"
:
(
"CHAR_MAX"
,
"UCHAR_MAX"
),
"short"
:
(
"SHRT_MAX"
,
"USHRT_MAX"
),
"int"
:
(
"INT_MAX"
,
"UINT_MAX"
),
"long"
:
(
"LONG_MAX"
,
"ULONG_MAX"
),
"PY_LONG_LONG"
:
(
Naming
.
LONG_LONG_MAX
,
Naming
.
ULONG_LONG_MAX
),
# CFloatType overrides max_value
}
RANK_INT
=
list
(
rank_to_type_name
).
index
(
'int'
)
RANK_LONG
=
list
(
rank_to_type_name
).
index
(
'long'
)
UNSIGNED
=
0
...
...
Cython/Shadow.py
View file @
6989e004
...
...
@@ -288,7 +288,8 @@ class CythonDotParallel(object):
__all__
=
[
'parallel'
,
'prange'
,
'threadid'
]
parallel
=
nogil
def
parallel
(
self
,
num_threads
=
None
):
return
nogil
def
prange
(
self
,
start
=
0
,
stop
=
None
,
step
=
1
,
schedule
=
None
,
nogil
=
False
):
if
stop
is
None
:
...
...
tests/run/sequential_parallel.pyx
View file @
6989e004
...
...
@@ -171,6 +171,53 @@ def test_pure_mode():
for
i
in
pure_parallel
.
prange
(
4
,
-
1
,
-
1
,
schedule
=
'dynamic'
,
nogil
=
True
):
print
i
with
pure_parallel
.
parallel
:
with
pure_parallel
.
parallel
()
:
print
pure_parallel
.
threadid
()
def
test_nan_init
():
"""
>>> test_nan_init()
"""
cdef
int
mybool
=
0
cdef
int
err
=
0
cdef
int
*
errp
=
&
err
cdef
signed
char
a1
=
10
cdef
unsigned
char
a2
=
10
cdef
short
b1
=
10
cdef
unsigned
short
b2
=
10
cdef
int
c1
=
10
cdef
unsigned
int
c2
=
10
cdef
long
d1
=
10
cdef
unsigned
long
d2
=
10
cdef
long
long
e1
=
10
cdef
unsigned
long
long
e2
=
10
cdef
float
f
=
10.0
cdef
double
g
=
10.0
cdef
long
double
h
=
10.0
cdef
void
*
p
=
<
void
*>
10
with
nogil
,
cython
.
parallel
.
parallel
():
# First, trick the error checking to make it believe these variables
# are initialized after this if
if
mybool
:
# mybool is always false!
a1
=
a2
=
b1
=
b2
=
c1
=
c2
=
d1
=
d2
=
e1
=
e2
=
0
f
=
g
=
h
=
0.0
p
=
NULL
if
(
a1
==
10
or
a2
==
10
or
b1
==
10
or
b2
==
10
or
c1
==
10
or
c2
==
10
or
d1
==
10
or
d2
==
10
or
e1
==
10
or
e2
==
10
or
f
==
10.0
or
g
==
10.0
or
h
==
10.0
or
p
!=
NULL
):
errp
[
0
]
=
1
if
err
:
raise
Exception
(
"One of the values was not initiazed to a maximum "
"or NaN value"
)
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