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
2cd11fd8
Commit
2cd11fd8
authored
Jul 22, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
@cname for enum/struct in CythonUtilityCode + simple memslice indexing
parent
556722cb
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
257 additions
and
81 deletions
+257
-81
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+34
-24
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+8
-4
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+35
-17
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+43
-8
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+14
-3
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+4
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+11
-1
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.pxd
+2
-2
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+11
-6
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+3
-0
Cython/Compiler/TreeFragment.py
Cython/Compiler/TreeFragment.py
+6
-3
Cython/Compiler/UtilityCode.py
Cython/Compiler/UtilityCode.py
+2
-1
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+26
-9
Cython/Utility/MemoryView_C.c
Cython/Utility/MemoryView_C.c
+7
-3
tests/run/cythonarray.pyx
tests/run/cythonarray.pyx
+14
-0
tests/run/memslice_indexing.pyx
tests/run/memslice_indexing.pyx
+37
-0
No files found.
Cython/Compiler/Buffer.py
View file @
2cd11fd8
...
...
@@ -93,7 +93,7 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
return
aux_var
auxvars
=
((
PyrexTypes
.
c_pyx_buffer_nd_type
,
Naming
.
pybuffernd_prefix
),
(
PyrexTypes
.
c_pyx_buffer_type
,
Naming
.
pybufferstruct_prefix
))
(
PyrexTypes
.
c_pyx_buffer_type
,
Naming
.
pybufferstruct_prefix
))
pybuffernd
,
rcbuffer
=
[
decvar
(
type
,
prefix
)
for
(
type
,
prefix
)
in
auxvars
]
entry
.
buffer_aux
=
Symtab
.
BufferAux
(
pybuffernd
,
rcbuffer
)
...
...
@@ -195,15 +195,26 @@ def analyse_buffer_options(globalpos, env, posargs, dictargs, defaults=None, nee
# Code generation
#
def
get_buf_suboffsetvars
(
entry
):
return
[(
"%s.diminfo[%d].suboffsets"
%
\
(
entry
.
buffer_aux
.
buflocal_nd_var
.
cname
,
i
))
for
i
in
range
(
entry
.
type
.
ndim
)]
def
get_buf_stridevars
(
entry
):
return
[(
"%s.diminfo[%d].strides"
%
\
(
entry
.
buffer_aux
.
buflocal_nd_var
.
cname
,
i
))
for
i
in
range
(
entry
.
type
.
ndim
)]
def
get_buf_shapevars
(
entry
):
return
[(
"%s.diminfo[%d].shape"
%
\
(
entry
.
buffer_aux
.
buflocal_nd_var
.
cname
,
i
))
for
i
in
range
(
entry
.
type
.
ndim
)]
class
BufferEntry
(
object
):
def
__init__
(
self
,
entry
):
self
.
entry
=
entry
self
.
type
=
entry
.
type
self
.
cname
=
entry
.
buffer_aux
.
buflocal_nd_var
.
cname
self
.
buf_ptr
=
"%s.rcbuffer->pybuffer.buf"
%
self
.
cname
self
.
buf_ptr_type
=
self
.
entry
.
type
.
buffer_ptr_type
def
get_buf_suboffsetvars
(
self
):
return
self
.
_for_all_ndim
(
"%s.diminfo[%d].suboffsets"
)
def
get_buf_stridevars
(
self
):
return
self
.
_for_all_ndim
(
"%s.diminfo[%d].strides"
)
def
get_buf_shapevars
(
self
):
return
self
.
_for_all_ndim
(
"%s.diminfo[%d].shape"
)
def
_for_all_ndim
(
self
,
s
):
return
[
s
%
(
self
.
cname
,
i
)
for
i
in
range
(
self
.
type
.
ndim
)]
def
get_flags
(
buffer_aux
,
buffer_type
):
flags
=
'PyBUF_FORMAT'
...
...
@@ -358,7 +369,8 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buf_entry,
code
.
putln
(
"}"
)
# Release stack
def
put_buffer_lookup_code
(
entry
,
index_signeds
,
index_cnames
,
directives
,
pos
,
code
):
def
put_buffer_lookup_code
(
entry
,
index_signeds
,
index_cnames
,
directives
,
pos
,
code
,
negative_indices
):
"""
Generates code to process indices and calculate an offset into
a buffer. Returns a C string which gives a pointer which can be
...
...
@@ -370,11 +382,9 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
body. The lookup however is delegated to a inline function that is instantiated
once per ndim (lookup with suboffsets tend to get quite complicated).
entry is a BufferEntry
"""
bufaux
=
entry
.
buffer_aux
pybuffernd_struct
=
bufaux
.
buflocal_nd_var
.
cname
# bufstruct = bufaux.buffer_info_var.cname
negative_indices
=
directives
[
'wraparound'
]
and
entry
.
type
.
negative_indices
negative_indices
=
directives
[
'wraparound'
]
and
negative_indices
if
directives
[
'boundscheck'
]:
# Check bounds and fix negative indices.
...
...
@@ -384,7 +394,7 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
tmp_cname
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
c_int_type
,
manage_ref
=
False
)
code
.
putln
(
"%s = -1;"
%
tmp_cname
)
for
dim
,
(
signed
,
cname
,
shape
)
in
enumerate
(
zip
(
index_signeds
,
index_cnames
,
get_buf_shapevars
(
entry
))):
entry
.
get_buf_shapevars
(
))):
if
signed
!=
0
:
# not unsigned, deal with negative index
code
.
putln
(
"if (%s < 0) {"
%
cname
)
...
...
@@ -412,7 +422,7 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
elif
negative_indices
:
# Only fix negative indices.
for
signed
,
cname
,
shape
in
zip
(
index_signeds
,
index_cnames
,
get_buf_shapevars
(
entry
)):
entry
.
get_buf_shapevars
(
)):
if
signed
!=
0
:
code
.
putln
(
"if (%s < 0) %s += %s;"
%
(
cname
,
cname
,
shape
))
...
...
@@ -423,7 +433,9 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
nd
=
entry
.
type
.
ndim
mode
=
entry
.
type
.
mode
if
mode
==
'full'
:
for
i
,
s
,
o
in
zip
(
index_cnames
,
get_buf_stridevars
(
entry
),
get_buf_suboffsetvars
(
entry
)):
for
i
,
s
,
o
in
zip
(
index_cnames
,
entry
.
get_buf_stridevars
(),
entry
.
get_buf_suboffsetvars
()):
params
.
append
(
i
)
params
.
append
(
s
)
params
.
append
(
o
)
...
...
@@ -441,7 +453,7 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
funcgen
=
buf_lookup_fortran_code
else
:
assert
False
for
i
,
s
in
zip
(
index_cnames
,
get_buf_stridevars
(
entry
)):
for
i
,
s
in
zip
(
index_cnames
,
entry
.
get_buf_stridevars
(
)):
params
.
append
(
i
)
params
.
append
(
s
)
...
...
@@ -452,11 +464,9 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
defcode
=
code
.
globalstate
[
'utility_code_def'
]
funcgen
(
protocode
,
defcode
,
name
=
funcname
,
nd
=
nd
)
ptr_type
=
entry
.
type
.
buffer_ptr_type
ptrcode
=
"%s(%s, %s.rcbuffer->pybuffer.buf, %s)"
%
(
funcname
,
ptr_type
.
declaration_code
(
""
),
pybuffernd_struct
,
", "
.
join
(
params
))
buf_ptr_type_code
=
entry
.
buf_ptr_type
.
declaration_code
(
""
)
ptrcode
=
"%s(%s, %s, %s)"
%
(
funcname
,
buf_ptr_type_code
,
entry
.
buf_ptr
,
", "
.
join
(
params
))
return
ptrcode
...
...
Cython/Compiler/Code.py
View file @
2cd11fd8
...
...
@@ -49,9 +49,15 @@ class UtilityCodeBase(object):
_utility_cache
=
{}
@
classmethod
def
_add_utility
(
self
,
utility
,
type
,
lines
,
begin_lineno
):
def
_add_utility
(
cls
,
utility
,
type
,
lines
,
begin_lineno
):
if
utility
:
code
=
'
\
n
'
*
begin_lineno
+
''
.
join
(
lines
)
if
cls
.
is_cython_utility
:
# Don't forget our line number
code
=
'
\
n
'
*
begin_lineno
+
''
.
join
(
lines
)
else
:
# line numbers are not important here
code
=
'
\
n
'
.
join
(
lines
)
if
type
==
'Proto'
:
utility
[
0
]
=
code
else
:
...
...
@@ -74,8 +80,6 @@ class UtilityCodeBase(object):
comment
=
'//'
regex
=
r'%s\
s*U
tility(Proto|Code)\
s*:
\s*((\
w|
\.)+)\
s*
' % comment
flags = re.DOTALL
utilities = {}
lines = []
...
...
Cython/Compiler/ExprNodes.py
View file @
2cd11fd8
...
...
@@ -2209,6 +2209,10 @@ class IndexNode(ExprNode):
subexprs
=
[
'base'
,
'index'
,
'indices'
]
indices
=
None
# Whether we're assigning to a buffer (in that case it needs to be
# writable)
writable_needed
=
False
def
__init__
(
self
,
pos
,
index
,
*
args
,
**
kw
):
ExprNode
.
__init__
(
self
,
pos
,
index
=
index
,
*
args
,
**
kw
)
self
.
_index
=
index
...
...
@@ -2341,8 +2345,8 @@ class IndexNode(ExprNode):
skip_child_analysis
=
False
buffer_access
=
False
memoryviewslice_access
=
False
if
self
.
base
.
type
.
is_buffer
:
#
memoryviewslice_access = False
if
self
.
base
.
type
.
is_buffer
or
self
.
base
.
type
.
is_memoryviewslice
:
if
self
.
indices
:
indices
=
self
.
indices
else
:
...
...
@@ -2360,11 +2364,11 @@ class IndexNode(ExprNode):
if
buffer_access
:
assert
hasattr
(
self
.
base
,
"entry"
)
# Must be a NameNode-like node
if
self
.
base
.
type
.
is_memoryviewslice
:
assert
hasattr
(
self
.
base
,
"entry"
)
if
self
.
indices
or
not
isinstance
(
self
.
index
,
EllipsisNode
):
error
(
self
.
pos
,
"Memoryviews currently support ellipsis indexing only."
)
else
:
memoryviewslice_access
=
True
#
if self.base.type.is_memoryviewslice:
#
assert hasattr(self.base, "entry")
#
if self.indices or not isinstance(self.index, EllipsisNode):
#
error(self.pos, "Memoryviews currently support ellipsis indexing only.")
#
else: memoryviewslice_access = True
# On cloning, indices is cloned. Otherwise, unpack index into indices
assert
not
(
buffer_access
and
isinstance
(
self
.
index
,
CloneNode
))
...
...
@@ -2382,13 +2386,15 @@ class IndexNode(ExprNode):
if
not
self
.
base
.
entry
.
type
.
writable
:
error
(
self
.
pos
,
"Writing to readonly buffer"
)
else
:
self
.
base
.
entry
.
buffer_aux
.
writable_needed
=
True
self
.
writable_needed
=
True
if
self
.
type
.
is_buffer
:
self
.
base
.
entry
.
buffer_aux
.
writable_needed
=
True
elif
memoryviewslice_access
:
self
.
type
=
self
.
base
.
type
self
.
is_memoryviewslice_access
=
True
if
getting
:
error
(
self
.
pos
,
"memoryviews currently support setting only."
)
#
elif memoryviewslice_access:
#
self.type = self.base.type
#
self.is_memoryviewslice_access = True
#
if getting:
#
error(self.pos, "memoryviews currently support setting only.")
else
:
base_type
=
self
.
base
.
type
...
...
@@ -2680,18 +2686,30 @@ class IndexNode(ExprNode):
def
buffer_lookup_code
(
self
,
code
):
# Assign indices to temps
index_temps
=
[
code
.
funcstate
.
allocate_temp
(
i
.
type
,
manage_ref
=
False
)
for
i
in
self
.
indices
]
index_temps
=
[
code
.
funcstate
.
allocate_temp
(
i
.
type
,
manage_ref
=
False
)
for
i
in
self
.
indices
]
for
temp
,
index
in
zip
(
index_temps
,
self
.
indices
):
code
.
putln
(
"%s = %s;"
%
(
temp
,
index
.
result
()))
# Generate buffer access code using these temps
import
Buffer
import
Buffer
,
MemoryView
# The above could happen because child_attrs is wrong somewhere so that
# options are not propagated.
return
Buffer
.
put_buffer_lookup_code
(
entry
=
self
.
base
.
entry
,
entry
=
self
.
base
.
entry
if
entry
.
type
.
is_buffer
:
buffer_entry
=
Buffer
.
BufferEntry
(
entry
)
negative_indices
=
entry
.
type
.
negative_indices
else
:
buffer_entry
=
MemoryView
.
MemoryViewSliceBufferEntry
(
entry
)
negative_indices
=
Buffer
.
buffer_defaults
[
'negative_indices'
]
return
Buffer
.
put_buffer_lookup_code
(
entry
=
buffer_entry
,
index_signeds
=
[
i
.
type
.
signed
for
i
in
self
.
indices
],
index_cnames
=
index_temps
,
directives
=
code
.
globalstate
.
directives
,
pos
=
self
.
pos
,
code
=
code
)
pos
=
self
.
pos
,
code
=
code
,
negative_indices
=
negative_indices
)
def
put_nonecheck
(
self
,
code
):
code
.
globalstate
.
use_utility_code
(
raise_noneindex_error_utility_code
)
...
...
Cython/Compiler/MemoryView.py
View file @
2cd11fd8
...
...
@@ -6,7 +6,7 @@ from Code import UtilityCode
from
UtilityCode
import
CythonUtilityCode
from
PyrexTypes
import
py_object_type
,
cython_memoryview_ptr_type
import
Buffer
import
PyrexTypes
START_ERR
=
"there must be nothing or the value 0 (zero) in the start slot."
STOP_ERR
=
"Axis specification only allowed in the 'stop' slot."
...
...
@@ -112,7 +112,7 @@ def put_assign_to_memviewslice(lhs_cname, rhs_cname, memviewslicetype, pos, code
for
i
in
range
(
ndim
):
code
.
putln
(
"%s.shape[%d] = %s.shape[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
code
.
putln
(
"%s.strides[%d] = %s.strides[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
code
.
putln
(
"%s.suboffsets[%d] = %s.suboffsets[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
#
code.putln("%s.suboffsets[%d] = %s.suboffsets[%d];" % (lhs_cname, i, rhs_cname, i))
def
get_buf_flag
(
specs
):
is_c_contig
,
is_f_contig
=
is_cf_contig
(
specs
)
...
...
@@ -173,6 +173,28 @@ def src_conforms_to_dst(src, dst):
return
True
class
MemoryViewSliceBufferEntry
(
Buffer
.
BufferEntry
):
def
__init__
(
self
,
entry
):
self
.
entry
=
entry
self
.
type
=
entry
.
type
self
.
cname
=
entry
.
cname
self
.
buf_ptr
=
"%s.data"
%
self
.
cname
dtype
=
self
.
entry
.
type
.
dtype
dtype
=
PyrexTypes
.
CPtrType
(
dtype
)
self
.
buf_ptr_type
=
dtype
def
get_buf_suboffsetvars
(
self
):
return
self
.
_for_all_ndim
(
"%s.memview->view.suboffsets[%d]"
)
def
get_buf_stridevars
(
self
):
return
self
.
_for_all_ndim
(
"%s.strides[%d]"
)
def
get_buf_shapevars
(
self
):
return
self
.
_for_all_ndim
(
"%s.shape[%d]"
)
def
get_copy_func_name
(
to_memview
):
base
=
"__Pyx_BufferNew_%s_From_%s_%s"
if
to_memview
.
is_c_contig
:
...
...
@@ -245,7 +267,7 @@ static int %s(const __Pyx_memviewslice mvs) {
%(for_loop)s {
#ifdef DEBUG
printf("mvs.suboffsets[i] %%d
\
\
n", mvs.suboffsets[i]);
/* printf("mvs.suboffsets[i] %%d
\
\
n", mvs.suboffsets[i]); */
printf("mvs.strides[i] %%d
\
\
n", mvs.strides[i]);
printf("mvs.shape[i] %%d
\
\
n", mvs.shape[i]);
printf("size %%d
\
\
n", size);
...
...
@@ -253,7 +275,7 @@ static int %s(const __Pyx_memviewslice mvs) {
#endif
#undef DEBUG
if(mvs.suboffsets[i] >= 0) {
if(mvs.
memview->view.
suboffsets[i] >= 0) {
return 0;
}
if(size * itemsize != mvs.strides[i]) {
...
...
@@ -595,6 +617,20 @@ def is_cf_contig(specs):
return
is_c_contig
,
is_f_contig
def
get_mode
(
specs
):
is_c_contig
,
is_f_contig
=
is_cf_contig
(
specs
)
if
is_c_contig
:
return
'c'
elif
is_f_contig
:
return
'fortran'
for
access
,
packing
in
specs
:
if
access
in
(
'ptr'
,
'full'
):
return
'full'
return
'strided'
def
validate_axes_specs
(
pos
,
specs
):
packing_specs
=
(
'contig'
,
'strided'
,
'follow'
)
...
...
@@ -622,7 +658,6 @@ def validate_axes_specs(pos, specs):
if
not
(
is_c_contig
or
is_f_contig
):
raise
CompileError
(
pos
,
"Invalid use of the follow specifier."
)
def
_get_resolved_spec
(
env
,
spec
):
# spec must be a NameNode or an AttributeNode
if
isinstance
(
spec
,
NameNode
):
...
...
@@ -704,13 +739,13 @@ def load_memview_cy_utility(name, *args, **kwargs):
def
load_memview_c_utility
(
name
,
*
args
,
**
kwargs
):
return
UtilityCode
.
load_utility_from_file
(
"MemoryView.c"
,
name
,
*
args
,
**
kwargs
)
"MemoryView
_C
.c"
,
name
,
*
args
,
**
kwargs
)
def
load_memview_c_string
(
name
):
return
UtilityCode
.
load_utility_as_string
(
"MemoryView.c"
,
name
)
return
UtilityCode
.
load_utility_as_string
(
"MemoryView
_C
.c"
,
name
)
_
,
copy_template
=
UtilityCode
.
load_utility_as_string
(
"MemoryView.c"
,
"MemviewSliceCopyTemplate"
)
"MemoryView
_C
.c"
,
"MemviewSliceCopyTemplate"
)
fmt_dict
=
{
'memview_struct_name'
:
memview_objstruct_cname
,
...
...
Cython/Compiler/ModuleNode.py
View file @
2cd11fd8
...
...
@@ -65,10 +65,21 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
body
.
stats
.
extend
(
tree
.
stats
)
else
:
self
.
body
.
stats
.
append
(
tree
)
selfscope
=
self
.
scope
selfscope
.
utility_code_list
.
extend
(
scope
.
utility_code_list
)
self
.
scope
.
utility_code_list
.
extend
(
scope
.
utility_code_list
)
def
extend_if_not_in
(
L1
,
L2
):
for
x
in
L2
:
if
x
not
in
L1
:
L1
.
append
(
x
)
extend_if_not_in
(
self
.
scope
.
include_files
,
scope
.
include_files
)
extend_if_not_in
(
self
.
scope
.
included_files
,
scope
.
included_files
)
extend_if_not_in
(
self
.
scope
.
python_include_files
,
scope
.
python_include_files
)
if
merge_scope
:
selfscope
.
merge_in
(
scope
)
self
.
scope
.
merge_in
(
scope
)
def
analyse_declarations
(
self
,
env
):
if
Options
.
embed_pos_in_docstring
:
...
...
Cython/Compiler/Nodes.py
View file @
2cd11fd8
...
...
@@ -6977,11 +6977,15 @@ class CnameDecoratorNode(StatNode):
self
.
node
.
analyse_declarations
(
env
)
self
.
is_function
=
isinstance
(
self
.
node
,
FuncDefNode
)
is_struct_or_enum
=
isinstance
(
self
.
node
,
(
CStructOrUnionDefNode
,
CEnumDefNode
))
e
=
self
.
node
.
entry
if
self
.
is_function
:
e
.
cname
=
self
.
cname
e
.
func_cname
=
self
.
cname
elif
is_struct_or_enum
:
e
.
cname
=
e
.
type
.
cname
=
self
.
cname
else
:
scope
=
self
.
node
.
scope
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
2cd11fd8
...
...
@@ -1255,7 +1255,7 @@ class CnameDirectivesTransform(CythonTransform, SkipDeclarations):
"""
def
handle_function
(
self
,
node
):
if
not
node
.
decorators
:
if
not
getattr
(
node
,
'decorators'
,
None
)
:
return
self
.
visit_Node
(
node
)
for
i
,
decorator
in
enumerate
(
node
.
decorators
):
...
...
@@ -1289,6 +1289,8 @@ class CnameDirectivesTransform(CythonTransform, SkipDeclarations):
visit_FuncDefNode
=
handle_function
visit_CClassDefNode
=
handle_function
visit_CEnumDefNode
=
handle_function
visit_CStructOrUnionDefNode
=
handle_function
class
ForwardDeclareTypes
(
CythonTransform
):
...
...
@@ -1576,6 +1578,14 @@ if VALUE is not None:
self
.
visitchildren
(
node
)
return
None
def
visit_CnameDecoratorNode
(
self
,
node
):
self
.
visitchildren
(
node
)
if
not
node
.
node
:
return
None
return
node
def
create_Property
(
self
,
entry
):
if
entry
.
visibility
==
'public'
:
if
entry
.
type
.
is_pyobject
:
...
...
Cython/Compiler/Parsing.pxd
View file @
2cd11fd8
...
...
@@ -7,8 +7,8 @@ ctypedef object (*p_sub_expr_func)(object)
# entry points
cpdef
p_module
(
PyrexScanner
s
,
pxd
,
full_module_name
)
cpdef
p_code
(
PyrexScanner
s
,
level
=
*
)
cpdef
p_module
(
PyrexScanner
s
,
pxd
,
full_module_name
,
ctx
=*
)
cpdef
p_code
(
PyrexScanner
s
,
level
=
*
,
ctx
=*
)
# internal parser states
...
...
Cython/Compiler/Parsing.py
View file @
2cd11fd8
...
...
@@ -33,6 +33,7 @@ class Ctx(object):
nogil
=
0
namespace
=
None
templates
=
None
allow_struct_enum_decorator
=
False
def
__init__
(
self
,
**
kwds
):
self
.
__dict__
.
update
(
kwds
)
...
...
@@ -1754,7 +1755,8 @@ def p_statement(s, ctx, first_statement = 0):
s
.
error
(
'decorator not allowed here'
)
s
.
level
=
ctx
.
level
decorators
=
p_decorators
(
s
)
if
s
.
sy
not
in
(
'def'
,
'cdef'
,
'cpdef'
,
'class'
):
bad_toks
=
'def'
,
'cdef'
,
'cpdef'
,
'class'
if
not
ctx
.
allow_struct_enum_decorator
and
s
.
sy
not
in
bad_toks
:
s
.
error
(
"Decorators can only be followed by functions or classes"
)
elif
s
.
sy
==
'pass'
and
cdef_flag
:
# empty cdef block
...
...
@@ -1774,7 +1776,10 @@ def p_statement(s, ctx, first_statement = 0):
s
.
level
=
ctx
.
level
node
=
p_cdef_statement
(
s
,
ctx
(
overridable
=
overridable
))
if
decorators
is
not
None
:
if
not
isinstance
(
node
,
(
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
,
Nodes
.
CClassDefNode
)):
tup
=
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
,
Nodes
.
CClassDefNode
if
ctx
.
allow_struct_enum_decorator
:
tup
+=
Nodes
.
CStructOrUnionDefNode
,
Nodes
.
CEnumDefNode
if
not
isinstance
(
node
,
tup
):
s
.
error
(
"Decorators can only be followed by functions or classes"
)
node
.
decorators
=
decorators
return
node
...
...
@@ -2892,8 +2897,8 @@ def p_doc_string(s):
else
:
return
None
def
p_code
(
s
,
level
=
None
):
body
=
p_statement_list
(
s
,
C
tx
(
level
=
level
),
first_statement
=
1
)
def
p_code
(
s
,
level
=
None
,
ctx
=
Ctx
):
body
=
p_statement_list
(
s
,
c
tx
(
level
=
level
),
first_statement
=
1
)
if
s
.
sy
!=
'EOF'
:
s
.
error
(
"Syntax error in statement [%s,%s]"
%
(
repr
(
s
.
sy
),
repr
(
s
.
systring
)))
...
...
@@ -2915,7 +2920,7 @@ def p_compiler_directive_comments(s):
s
.
next
()
return
result
def
p_module
(
s
,
pxd
,
full_module_name
):
def
p_module
(
s
,
pxd
,
full_module_name
,
ctx
=
Ctx
):
pos
=
s
.
position
()
directive_comments
=
p_compiler_directive_comments
(
s
)
...
...
@@ -2930,7 +2935,7 @@ def p_module(s, pxd, full_module_name):
else
:
level
=
'module'
body
=
p_statement_list
(
s
,
Ctx
(
level
=
level
),
first_statement
=
1
)
body
=
p_statement_list
(
s
,
ctx
(
level
=
level
),
first_statement
=
1
)
if
s
.
sy
!=
'EOF'
:
s
.
error
(
"Syntax error in statement [%s,%s]"
%
(
repr
(
s
.
sy
),
repr
(
s
.
systring
)))
...
...
Cython/Compiler/PyrexTypes.py
View file @
2cd11fd8
...
...
@@ -368,11 +368,14 @@ class MemoryViewSliceType(PyrexType):
self
.
dtype
=
base_dtype
self
.
axes
=
axes
self
.
ndim
=
len
(
axes
)
import
MemoryView
self
.
is_c_contig
,
self
.
is_f_contig
=
MemoryView
.
is_cf_contig
(
self
.
axes
)
assert
not
(
self
.
is_c_contig
and
self
.
is_f_contig
)
self
.
mode
=
MemoryView
.
get_mode
(
axes
)
def
same_as_resolved_type
(
self
,
other_type
):
return
((
other_type
.
is_memoryviewslice
and
self
.
dtype
.
same_as
(
other_type
.
dtype
)
and
...
...
Cython/Compiler/TreeFragment.py
View file @
2cd11fd8
...
...
@@ -32,7 +32,7 @@ class StringParseContext(Main.Context):
return
ModuleScope
(
module_name
,
parent_module
=
None
,
context
=
self
)
def
parse_from_strings
(
name
,
code
,
pxds
=
{},
level
=
None
,
initial_pos
=
None
,
context
=
None
):
context
=
None
,
allow_struct_enum_decorator
=
False
):
"""
Utility method to parse a (unicode) string of code. This is mostly
used for internal Cython compiler purposes (creating code snippets
...
...
@@ -66,12 +66,15 @@ def parse_from_strings(name, code, pxds={}, level=None, initial_pos=None,
scanner
=
PyrexScanner
(
buf
,
code_source
,
source_encoding
=
encoding
,
scope
=
scope
,
context
=
context
,
initial_pos
=
initial_pos
)
ctx
=
Parsing
.
Ctx
(
allow_struct_enum_decorator
=
allow_struct_enum_decorator
)
if
level
is
None
:
tree
=
Parsing
.
p_module
(
scanner
,
0
,
module_name
)
tree
=
Parsing
.
p_module
(
scanner
,
0
,
module_name
,
ctx
=
ctx
)
tree
.
scope
=
scope
tree
.
is_pxd
=
False
else
:
tree
=
Parsing
.
p_code
(
scanner
,
level
=
level
)
tree
=
Parsing
.
p_code
(
scanner
,
level
=
level
,
ctx
=
ctx
)
tree
.
scope
=
scope
return
tree
...
...
Cython/Compiler/UtilityCode.py
View file @
2cd11fd8
...
...
@@ -86,7 +86,8 @@ class CythonUtilityCode(Code.UtilityCodeBase):
context
=
CythonUtilityCodeContext
(
self
.
name
)
context
.
prefix
=
self
.
prefix
#context = StringParseContext(self.name)
tree
=
parse_from_strings
(
self
.
name
,
self
.
pyx
,
context
=
context
)
tree
=
parse_from_strings
(
self
.
name
,
self
.
pyx
,
context
=
context
,
allow_struct_enum_decorator
=
True
)
pipeline
=
Pipeline
.
create_pipeline
(
context
,
'pyx'
,
exclude_classes
=
excludes
)
if
entries_only
:
...
...
Cython/Utility/MemoryView.pyx
View file @
2cd11fd8
...
...
@@ -11,6 +11,7 @@ cdef extern from "Python.h":
PyBUF_F_CONTIGUOUS
,
PyBUF_ANY_CONTIGUOUS
@
cname
(
"__pyx_array"
)
cdef
class
array
:
...
...
@@ -87,10 +88,6 @@ cdef class array:
self
.
data
=
<
char
*>
malloc
(
self
.
len
)
if
not
self
.
data
:
raise
MemoryError
(
"unable to allocate array data."
)
else
:
self
.
data
=
NULL
self
.
callback_free_data
=
NULL
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
...
...
@@ -139,6 +136,21 @@ cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *
# UtilityCode: MemoryView
# from cpython cimport ...
cdef
extern
from
"pythread.h"
:
ctypedef
void
*
PyThread_type_lock
PyThread_type_lock
PyThread_allocate_lock
()
void
PyThread_free_lock
(
PyThread_type_lock
)
int
PyThread_acquire_lock
(
PyThread_type_lock
,
int
mode
)
nogil
void
PyThread_release_lock
(
PyThread_type_lock
)
nogil
cdef
extern
from
*
:
int
__Pyx_GetBuffer
(
object
,
Py_buffer
*
,
int
)
void
__Pyx_ReleaseBuffer
(
Py_buffer
*
)
@
cname
(
'__pyx_MemviewEnum'
)
cdef
class
Enum
(
object
):
cdef
object
name
...
...
@@ -147,6 +159,7 @@ cdef class Enum(object):
def
__repr__
(
self
):
return
self
.
name
cdef
strided
=
Enum
(
"<strided axis packing mode>"
)
cdef
contig
=
Enum
(
"<contig axis packing mode>"
)
cdef
follow
=
Enum
(
"<follow axis packing mode>"
)
...
...
@@ -154,25 +167,29 @@ cdef direct = Enum("<direct axis access mode>")
cdef
ptr
=
Enum
(
"<ptr axis access mode>"
)
cdef
full
=
Enum
(
"<full axis access mode>"
)
cdef
extern
from
*
:
int
__Pyx_GetBuffer
(
object
,
Py_buffer
*
,
int
)
void
__Pyx_ReleaseBuffer
(
Py_buffer
*
)
@
cname
(
'__pyx_memoryview'
)
cdef
class
memoryview
(
object
):
cdef
object
obj
cdef
Py_buffer
view
cdef
int
gotbuf_flag
cdef
PyThread_type_lock
acqcnt_lock
cdef
int
acquisition_count
def
__cinit__
(
memoryview
self
,
object
obj
,
int
flags
):
self
.
obj
=
obj
__Pyx_GetBuffer
(
self
.
obj
,
&
self
.
view
,
flags
)
#self.acqcnt_lock = PyThread_allocate_lock()
#if self.acqcnt_lock == NULL:
# raise MemoryError
__Pyx_GetBuffer
(
obj
,
&
self
.
view
,
flags
)
def
__dealloc__
(
memoryview
self
):
#PyThread_free_lock(self.acqcnt_lock)
self
.
obj
=
None
__Pyx_ReleaseBuffer
(
&
self
.
view
)
@
cname
(
'__pyx_memoryview_new'
)
cdef
memoryview
memoryview_cwrapper
(
object
o
,
int
flags
):
return
memoryview
(
o
,
flags
)
Cython/Utility/MemoryView.c
→
Cython/Utility/MemoryView
_C
.c
View file @
2cd11fd8
...
...
@@ -4,10 +4,11 @@
typedef
struct
{
struct
%
(
memview_struct_name
)
s
*
memview
;
/* For convenience and faster access */
char
*
data
;
Py_ssize_t
shape
[
%
(
max_dims
)
d
];
Py_ssize_t
strides
[
%
(
max_dims
)
d
];
Py_ssize_t
suboffsets
[
%
(
max_dims
)
d
];
/* Py_ssize_t suboffsets[%(max_dims)d]; */
}
%
(
memviewslice_name
)
s
;
// UtilityProto: MemviewSliceInit
...
...
@@ -24,6 +25,8 @@ typedef struct {
#define __Pyx_IS_C_CONTIG 1
#define __Pyx_IS_F_CONTIG 2
/* #define __PYX_MEMSLICE_GETDATA(SLICE) ((char *) SLICE->memview->view->buf) */
static
int
__Pyx_ValidateAndInit_memviewslice
(
struct
__pyx_memoryview_obj
*
memview
,
int
*
axes_specs
,
int
c_or_f_flag
,
int
ndim
,
__Pyx_TypeInfo
*
dtype
,
__Pyx_BufFmt_StackElem
stack
[],
__Pyx_memviewslice
*
memviewslice
);
...
...
@@ -40,7 +43,7 @@ static int __Pyx_ValidateAndInit_memviewslice(
int
*
axes_specs
,
int
c_or_f_flag
,
int
ndim
,
__Pyx_TypeInfo
*
dtype
,
__Pyx_TypeInfo
*
dtype
,
__Pyx_BufFmt_StackElem
stack
[],
__Pyx_memviewslice
*
memviewslice
)
{
...
...
@@ -191,11 +194,12 @@ static int __Pyx_init_memviewslice(
for
(
i
=
0
;
i
<
ndim
;
i
++
)
{
memviewslice
->
strides
[
i
]
=
buf
->
strides
[
i
];
memviewslice
->
shape
[
i
]
=
buf
->
shape
[
i
];
/*
if(buf->suboffsets) {
memviewslice->suboffsets[i] = buf->suboffsets[i];
} else {
memviewslice->suboffsets[i] = -1;
}
}
*/
}
__Pyx_INCREF
((
PyObject
*
)
memview
);
...
...
tests/run/cythonarray.pyx
View file @
2cd11fd8
...
...
@@ -55,3 +55,17 @@ def full_or_strided():
cy
.
array
(
shape
=
(
10
,
10
),
itemsize
=
sizeof
(
float
),
format
=
'f'
,
mode
=
'c'
)
cdef
object
[
long
long
int
,
ndim
=
3
,
mode
=
'strided'
]
stridedbuf
=
\
cy
.
array
(
shape
=
(
1
,
2
,
3
),
itemsize
=
sizeof
(
long
long
int
),
format
=
'q'
,
mode
=
'fortran'
)
def
dont_allocate_buffer
():
"""
>>> dont_allocate_buffer()
callback called 1
"""
cdef
cy
.
array
result
=
cy
.
array
((
10
,
10
),
itemsize
=
sizeof
(
int
),
format
=
'i'
,
allocate_buffer
=
False
)
assert
result
.
data
==
NULL
result
.
data
=
<
char
*>
1
result
.
callback_free_data
=
callback
result
=
None
cdef
void
callback
(
char
*
data
):
print
"callback called %d"
%
<
long
>
data
tests/run/memslice_indexing.pyx
0 → 100644
View file @
2cd11fd8
cimport
cython
from
cython
cimport
array
from
libc.stdlib
cimport
malloc
,
free
def
create_array
(
shape
,
mode
=
'c'
):
cdef
array
result
=
array
(
shape
,
itemsize
=
sizeof
(
int
),
format
=
'i'
,
mode
=
mode
)
cdef
int
*
data
=
<
int
*>
result
.
data
cdef
int
i
,
j
,
value
for
i
in
range
(
shape
[
0
]):
for
j
in
range
(
shape
[
1
]):
value
=
i
*
shape
[
0
]
+
j
if
mode
==
'fortran'
:
data
[
i
+
j
*
10
]
=
value
else
:
data
[
value
]
=
value
return
result
def
slice_contig_indexing
():
"""
>>> slice_contig_indexing()
98
61
98
61
"""
cdef
int
[:,
::
1
]
carr
=
create_array
((
14
,
10
))
cdef
int
[::
1
,
:]
farr
=
create_array
((
10
,
14
),
mode
=
'fortran'
)
print
carr
[
9
,
8
]
print
carr
[
6
,
1
]
print
farr
[
9
,
8
]
print
farr
[
6
,
1
]
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