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
Xavier Thompson
cython
Commits
917cce5e
Commit
917cce5e
authored
Aug 04, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support casting pointers to cython.array
parent
d7322d2f
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
608 additions
and
210 deletions
+608
-210
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+22
-7
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+6
-1
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+10
-17
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+161
-0
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+27
-14
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+2
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+16
-4
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+6
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+5
-4
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+9
-10
Cython/Compiler/UtilityCode.py
Cython/Compiler/UtilityCode.py
+7
-8
Cython/Utility/Buffer.c
Cython/Utility/Buffer.c
+74
-12
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+181
-77
Cython/Utility/MemoryView_C.c
Cython/Utility/MemoryView_C.c
+12
-10
tests/run/cythonarray.pyx
tests/run/cythonarray.pyx
+70
-8
tests/run/memoryview.pyx
tests/run/memoryview.pyx
+0
-36
No files found.
Cython/Compiler/Buffer.py
View file @
917cce5e
...
...
@@ -5,7 +5,7 @@ from ExprNodes import *
from
StringEncoding
import
EncodedString
from
Errors
import
CompileError
from
UtilityCode
import
CythonUtilityCode
from
Code
import
UtilityCode
from
Code
import
UtilityCode
,
ContentHashingUtilityCode
import
Cython.Compiler.Options
import
Interpreter
import
PyrexTypes
...
...
@@ -34,10 +34,11 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
assert
isinstance
(
node
,
ModuleNode
)
self
.
max_ndim
=
0
result
=
super
(
IntroduceBufferAuxiliaryVars
,
self
).
__call__
(
node
)
if
self
.
buffers_exists
or
self
.
using_memoryview
:
if
self
.
buffers_exists
:
use_bufstruct_declare_code
(
node
.
scope
)
use_py2_buffer_functions
(
node
.
scope
)
use_empty_bufstruct_code
(
node
.
scope
,
self
.
max_ndim
)
node
.
scope
.
use_utility_code
(
empty_bufstruct_utility
)
return
result
...
...
@@ -476,13 +477,15 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives,
def
use_bufstruct_declare_code
(
env
):
env
.
use_utility_code
(
buffer_struct_declare_code
)
def
use_empty_bufstruct_code
(
env
,
max_ndim
):
def
get_empty_bufstruct_code
(
max_ndim
):
code
=
dedent
(
"""
Py_ssize_t __Pyx_zeros[] = {%s};
Py_ssize_t __Pyx_minusones[] = {%s};
"""
)
%
(
", "
.
join
([
"0"
]
*
max_ndim
),
", "
.
join
([
"-1"
]
*
max_ndim
))
env
.
use_utility_code
(
UtilityCode
(
proto
=
code
)
)
return
UtilityCode
(
proto
=
code
)
empty_bufstruct_utility
=
get_empty_bufstruct_code
(
Options
.
buffer_max_dims
)
def
buf_lookup_full_code
(
proto
,
defin
,
name
,
nd
):
"""
...
...
@@ -725,12 +728,18 @@ def get_type_information_cname(code, dtype, maxdepth=None):
print
dtype
assert
False
typecode
.
putln
((
'static __Pyx_TypeInfo %s = { "%s", %s, sizeof(%s),
\
'
%s
\
'
};'
if
dtype
.
is_int
:
is_unsigned
=
"IS_UNSIGNED(%s)"
%
declcode
else
:
is_unsigned
=
"0"
typecode
.
putln
((
'static __Pyx_TypeInfo %s = { "%s", %s, sizeof(%s),
\
'
%s
\
'
, %s };'
)
%
(
name
,
rep
,
structinfo_name
,
declcode
,
typegroup
,
is_unsigned
,
),
safe
=
True
)
return
name
...
...
@@ -753,5 +762,11 @@ impl = """
"""
)
raise_buffer_fallback_code
=
load_buffer_utility
(
"BufferFallbackError"
)
buffer_structs_code
=
load_buffer_utility
(
"BufferFormatStructs"
)
acquire_utility_code
=
load_buffer_utility
(
"BufferFormatCheck"
,
context
=
context
)
\ No newline at end of file
context
=
context
,
requires
=
[
buffer_structs_code
])
# See utility code BufferFormatFromTypeInfo
_typeinfo_to_format_code
=
load_buffer_utility
(
"TypeInfoToFormat"
,
context
=
{},
requires
=
[
buffer_structs_code
])
\ No newline at end of file
Cython/Compiler/Code.py
View file @
917cce5e
...
...
@@ -318,7 +318,12 @@ class ContentHashingUtilityCode(UtilityCode):
return
hash
((
self
.
proto
,
self
.
impl
))
def
__eq__
(
self
,
other
):
return
(
self
.
proto
,
self
.
impl
)
==
(
other
.
proto
,
other
.
impl
)
if
not
isinstance
(
other
,
type
(
self
)):
return
False
self_proto
=
getattr
(
self
,
'proto'
,
None
)
other_proto
=
getattr
(
other
,
'proto'
,
None
)
return
(
self_proto
,
self
.
impl
)
==
(
other_proto
,
other
.
impl
)
class
LazyUtilityCode
(
UtilityCodeBase
):
...
...
Cython/Compiler/CythonScope.py
View file @
917cce5e
...
...
@@ -71,12 +71,14 @@ class CythonScope(ModuleScope):
# self.test_cythonscope()
def
test_cythonscope
(
self
):
# A special function just to make it easy to test the scope and
# utility code functionality in isolation. It is available to
# "end-users" but nobody will know it is there anyway...
"""
Creates some entries for testing purposes and entries for
cython.array() and for cython.view.*.
"""
cython_testscope_utility_code
.
declare_in_scope
(
self
)
cython_test_extclass_utility_code
.
declare_in_scope
(
self
)
cython_array_utility_code
.
declare_in_scope
(
self
)
MemoryView
.
cython_array_utility_code
.
declare_in_scope
(
self
)
#
# The view sub-scope
...
...
@@ -92,7 +94,9 @@ class CythonScope(ModuleScope):
cythonview_testscope_utility_code
.
declare_in_scope
(
viewscope
)
view_utility_code
.
declare_in_scope
(
viewscope
)
view_utility_scope
=
MemoryView
.
view_utility_code
.
declare_in_scope
(
viewscope
)
MemoryView
.
memview_fromslice_utility_code
.
from_scope
=
view_utility_scope
MemoryView
.
memview_fromslice_utility_code
.
declare_in_scope
(
viewscope
)
def
create_cython_scope
(
context
,
create_testscope
):
...
...
@@ -132,15 +136,4 @@ cython_test_extclass_utility_code = \
requires
=
[
undecorated_methods_protos
,
test_cython_utility_dep
])
cythonview_testscope_utility_code
=
load_testscope_utility
(
"View.TestScope"
)
view_utility_code
=
MemoryView
.
load_memview_cy_utility
(
"View.MemoryView"
,
context
=
MemoryView
.
context
,
requires
=
[
Buffer
.
GetAndReleaseBufferUtilityCode
(),
MemoryView
.
memviewslice_declare_code
],
)
cython_array_utility_code
=
MemoryView
.
load_memview_cy_utility
(
"CythonArray"
,
context
=
MemoryView
.
context
,
requires
=
[
view_utility_code
])
cythonview_testscope_utility_code
=
load_testscope_utility
(
"View.TestScope"
)
\ No newline at end of file
Cython/Compiler/ExprNodes.py
View file @
917cce5e
...
...
@@ -584,6 +584,11 @@ class ExprNode(Node):
if
dst_type
.
is_reference
:
dst_type
=
dst_type
.
ref_base_type
if
self
.
coercion_type
is
not
None
:
# This is purely for error checking purposes!
node
=
NameNode
(
self
.
pos
,
name
=
''
,
type
=
self
.
coercion_type
)
node
.
coerce_to
(
dst_type
,
env
)
if
dst_type
.
is_memoryviewslice
:
import
MemoryView
if
not
src
.
type
.
is_memoryviewslice
:
...
...
@@ -747,6 +752,7 @@ class PyConstNode(AtomicExprNode):
class
NoneNode
(
PyConstNode
):
# The constant value None
is_none
=
1
value
=
"Py_None"
constant_result
=
None
...
...
@@ -6051,6 +6057,157 @@ class TypecastNode(ExprNode):
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
ERR_START
=
"Start may not be given"
ERR_NOT_STOP
=
"Stop must be provided to indicate shape"
ERR_STEPS
=
(
"Strides may only be given to indicate contiguity. "
"Consider slicing it after conversion"
)
ERR_NOT_POINTER
=
"Can only create cython.array from pointer"
ERR_BASE_TYPE
=
"Pointer base type does not match cython.array base type"
class
CythonArrayNode
(
ExprNode
):
"""
Used when a pointer of base_type is cast to a memoryviewslice with that
base type. i.e.
<int[::1, :]> p
creates a fortran-contiguous cython.array.
We leave the type set to object so coercions to object are more efficient
and less work. Acquiring a memoryviewslice from this will be just as
efficient. ExprNode.coerce_to() will do the additional typecheck on
self.compile_time_type
"""
subexprs
=
[
'operand'
,
'shapes'
]
shapes
=
None
is_temp
=
True
mode
=
"c"
shape_type
=
PyrexTypes
.
c_py_ssize_t_type
def
analyse_types
(
self
,
env
):
import
MemoryView
self
.
type
=
error_type
self
.
env
=
env
self
.
shapes
=
[]
for
axis_no
,
axis
in
enumerate
(
self
.
base_type_node
.
axes
):
if
not
axis
.
start
.
is_none
:
return
error
(
axis
.
start
.
pos
,
ERR_START
)
if
axis
.
stop
.
is_none
:
return
error
(
axis
.
pos
,
ERR_NOT_STOP
)
axis
.
stop
.
analyse_types
(
env
)
shape
=
axis
.
stop
.
coerce_to
(
self
.
shape_type
,
env
)
if
not
shape
.
is_literal
:
shape
.
coerce_to_temp
(
env
)
self
.
shapes
.
append
(
shape
)
if
not
axis
.
stop
.
type
.
is_int
:
return
error
(
axis
.
stop
.
pos
,
"Expected an integer type"
)
first_or_last
=
axis_no
in
(
0
,
len
(
self
.
base_type_node
.
axes
)
-
1
)
if
not
axis
.
step
.
is_none
and
first_or_last
:
axis
.
step
.
analyse_types
(
env
)
if
(
not
axis
.
step
.
type
.
is_int
and
axis
.
step
.
is_literal
and
not
axis
.
step
.
type
.
is_error
):
return
error
(
axis
.
step
.
pos
,
"Expected an integer literal"
)
if
axis
.
step
.
compile_time_value
(
env
)
!=
1
:
return
error
(
axis
.
step
.
pos
,
ERR_STEPS
)
if
axis_no
==
0
:
self
.
mode
=
"fortran"
elif
axis
.
step
and
not
first_or_last
:
return
error
(
axis
.
step
.
pos
,
ERR_STEPS
)
self
.
operand
.
analyse_types
(
env
)
array_dtype
=
self
.
base_type_node
.
base_type_node
.
analyse
(
env
)
if
not
self
.
operand
.
type
.
is_ptr
:
return
error
(
self
.
operand
.
pos
,
ERR_NOT_POINTER
)
elif
not
self
.
operand
.
type
.
base_type
.
same_as
(
array_dtype
):
return
error
(
self
.
operand
.
pos
,
ERR_BASE_TYPE
)
#self.operand = self.operand.coerce_to(PyrexTypes.c_char_ptr_type, env)
if
not
self
.
operand
.
is_name
:
self
.
operand
=
self
.
operand
.
coerce_to_temp
(
env
)
axes
=
[(
'direct'
,
'follow'
)]
*
len
(
self
.
base_type_node
.
axes
)
if
self
.
mode
==
"fortran"
:
axes
[
0
]
=
(
'direct'
,
'contig'
)
else
:
axes
[
-
1
]
=
(
'direct'
,
'contig'
)
self
.
coercion_type
=
PyrexTypes
.
MemoryViewSliceType
(
array_dtype
,
axes
)
#self.type = py_object_type
self
.
type
=
env
.
global_scope
().
context
.
cython_scope
.
lookup
(
"array"
).
type
assert
self
.
type
env
.
use_utility_code
(
MemoryView
.
cython_array_utility_code
)
env
.
use_utility_code
(
MemoryView
.
typeinfo_to_format_code
)
def
allocate_temp_result
(
self
,
code
):
if
self
.
temp_code
:
raise
RuntimeError
(
"temp allocated mulitple times"
)
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
self
.
type
,
True
)
def
generate_result_code
(
self
,
code
):
import
Buffer
shapes
=
[
self
.
shape_type
.
cast_code
(
shape
.
result
())
for
shape
in
self
.
shapes
]
dtype
=
self
.
coercion_type
.
dtype
shapes_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
format_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
itemsize
=
"sizeof(%s)"
%
dtype
.
declaration_code
(
""
)
type_info
=
Buffer
.
get_type_information_cname
(
code
,
dtype
)
code
.
putln
(
"if (!%s) {"
%
self
.
operand
.
result
())
code
.
putln
(
'PyErr_SetString(PyExc_ValueError,'
'"Cannot create cython.array from NULL pointer");'
)
code
.
putln
(
code
.
error_goto
(
self
.
operand
.
pos
))
code
.
putln
(
"}"
)
code
.
putln
(
"%s = __pyx_format_from_typeinfo(&%s);"
%
(
format_temp
,
type_info
))
code
.
putln
(
'%s = Py_BuildValue("(%s)", %s);'
%
(
shapes_temp
,
"n"
*
len
(
shapes
),
", "
.
join
(
shapes
)))
err
=
"!%s || !%s || !PyBytes_Check(%s)"
%
(
format_temp
,
shapes_temp
,
format_temp
)
code
.
putln
(
code
.
error_goto_if
(
err
,
self
.
pos
))
code
.
put_gotref
(
format_temp
)
code
.
put_gotref
(
shapes_temp
)
tup
=
(
self
.
result
(),
shapes_temp
,
itemsize
,
format_temp
,
self
.
mode
,
self
.
operand
.
result
())
code
.
putln
(
'%s = __pyx_array_new('
'%s, %s, PyBytes_AS_STRING(%s), '
'"%s", (char *) %s);'
%
tup
)
code
.
putln
(
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
))
code
.
put_gotref
(
self
.
result
())
def
dispose
(
temp
):
code
.
put_decref_clear
(
temp
,
py_object_type
)
code
.
funcstate
.
release_temp
(
temp
)
dispose
(
shapes_temp
)
dispose
(
format_temp
)
class
SizeofNode
(
ExprNode
):
# Abstract base class for sizeof(x) expression nodes.
...
...
@@ -7910,6 +8067,10 @@ class CoerceToPyTypeNode(CoercionNode):
# FIXME: check that the target type and the resulting type are compatible
pass
if
arg
.
type
.
is_memoryviewslice
:
# Register utility codes at this point
arg
.
type
.
get_to_py_function
(
env
,
arg
)
self
.
env
=
env
gil_message
=
"Converting to Python object"
...
...
Cython/Compiler/MemoryView.py
View file @
917cce5e
...
...
@@ -66,8 +66,6 @@ memview_typeptr_cname = '__pyx_memoryview_type'
memview_objstruct_cname
=
'__pyx_memoryview_obj'
memviewslice_cname
=
u'__Pyx_memviewslice'
def
put_init_entry
(
mv_cname
,
code
):
code
.
putln
(
"%s.data = NULL;"
%
mv_cname
)
code
.
putln
(
"%s.memview = NULL;"
%
mv_cname
)
...
...
@@ -129,18 +127,9 @@ def get_buf_flags(specs):
else
:
return
memview_strided_access
def
use_memview_util_code
(
env
):
import
CythonScope
env
.
use_utility_code
(
CythonScope
.
view_utility_code
)
env
.
use_utility_code
(
memviewslice_declare_code
)
def
use_memview_cwrap
(
env
):
import
CythonScope
env
.
use_utility_code
(
CythonScope
.
view_utility_code
)
def
use_cython_array
(
env
):
import
CythonScope
env
.
use_utility_code
(
CythonScope
.
cython_array_utility_code
)
env
.
use_utility_code
(
cython_array_utility_code
)
def
src_conforms_to_dst
(
src
,
dst
):
'''
...
...
@@ -778,7 +767,31 @@ memviewslice_declare_code = load_memview_c_utility(
memviewslice_init_code
=
load_memview_c_utility
(
"MemviewSliceInit"
,
context
=
dict
(
context
,
BUF_MAX_NDIMS
=
Options
.
buffer_max_dims
),
requires
=
[
memviewslice_declare_code
,
Buffer
.
acquire_utility_code
],
requires
=
[
memviewslice_declare_code
,
Buffer
.
acquire_utility_code
],
)
memviewslice_index_helpers
=
load_memview_c_utility
(
"MemviewSliceIndex"
)
typeinfo_to_format_code
=
load_memview_cy_utility
(
"BufferFormatFromTypeInfo"
,
requires
=
[
Buffer
.
_typeinfo_to_format_code
])
view_utility_code
=
load_memview_cy_utility
(
"View.MemoryView"
,
context
=
context
,
requires
=
[
Buffer
.
GetAndReleaseBufferUtilityCode
(),
Buffer
.
buffer_struct_declare_code
,
Buffer
.
empty_bufstruct_utility
,
memviewslice_init_code
],
)
memviewslice_index_helpers
=
load_memview_c_utility
(
"MemviewSliceIndex"
)
\ No newline at end of file
cython_array_utility_code
=
load_memview_cy_utility
(
"CythonArray"
,
context
=
context
,
requires
=
[
view_utility_code
])
memview_fromslice_utility_code
=
load_memview_cy_utility
(
"MemviewFromSlice"
,
context
=
context
,
requires
=
[
view_utility_code
],
)
\ No newline at end of file
Cython/Compiler/ModuleNode.py
View file @
917cce5e
...
...
@@ -2440,8 +2440,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type
.
typeptr_cname
,
type
.
typeobj_cname
))
def
generate_cfunction_declaration
(
entry
,
env
,
code
,
definition
):
from_cy_utility
=
entry
.
used
and
entry
.
utility_code_definition
if
entry
.
inline_func_in_pxd
or
(
not
entry
.
in_cinclude
and
(
definition
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
)):
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
or
from_cy_utility
)):
if
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
...
...
Cython/Compiler/Nodes.py
View file @
917cce5e
...
...
@@ -126,6 +126,7 @@ class Node(object):
__metaclass__
=
VerboseCodeWriter
is_name
=
0
is_none
=
0
is_literal
=
0
is_terminator
=
0
temps
=
None
...
...
@@ -137,6 +138,11 @@ class Node(object):
cf_state
=
None
# This may be an additional (or 'actual') type that will be checked when
# this node is coerced to another type. This could be useful to set when
# the actual type to which it can coerce is known, but you want to leave
# the type a py_object_type
coercion_type
=
None
def
__init__
(
self
,
pos
,
**
kw
):
self
.
pos
=
pos
...
...
@@ -823,12 +829,18 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
return
self
.
type
self
.
type
=
PyrexTypes
.
MemoryViewSliceType
(
base_type
,
axes_specs
)
MemoryView
.
use_memview_util_code
(
env
)
MemoryView
.
use_cython_array
(
env
)
MemoryView
.
use_memview_util_code
(
env
)
env
.
use_utility_code
(
MemoryView
.
memviewslice_declare_code
)
if
self
.
type
.
dtype
.
is_memoryviewslice
:
error
(
self
.
pos
,
"Memoryview slices may not be used as the "
"base type for memoryview slices"
)
self
.
use_memview_utilities
(
env
)
return
self
.
type
def
use_memview_utilities
(
self
,
env
):
import
MemoryView
env
.
use_utility_code
(
MemoryView
.
view_utility_code
)
class
CNestedBaseTypeNode
(
CBaseTypeNode
):
# For C++ classes that live inside other C++ classes.
...
...
Cython/Compiler/Parsing.py
View file @
917cce5e
...
...
@@ -297,7 +297,8 @@ def p_typecast(s):
pos
=
s
.
position
()
s
.
next
()
base_type
=
p_c_base_type
(
s
)
if
base_type
.
name
is
None
:
is_memslice
=
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
)
if
not
is_memslice
and
base_type
.
name
is
None
:
s
.
error
(
"Unknown type"
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
if
s
.
sy
==
'?'
:
...
...
@@ -307,6 +308,10 @@ def p_typecast(s):
typecheck
=
0
s
.
expect
(
">"
)
operand
=
p_factor
(
s
)
if
is_memslice
:
return
ExprNodes
.
CythonArrayNode
(
pos
,
base_type_node
=
base_type
,
operand
=
operand
)
return
ExprNodes
.
TypecastNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
917cce5e
...
...
@@ -553,14 +553,15 @@ class MemoryViewSliceType(PyrexType):
return
True
def
get_to_py_function
(
self
,
env
,
obj
):
import
MemoryView
env
.
use_utility_code
(
MemoryView
.
memview_fromslice_utility_code
)
to_py_func
,
from_py_func
=
self
.
dtype_object_conversion_funcs
(
env
)
to_py_func
=
"(PyObject *(*)(char *)) "
+
to_py_func
from_py_func
=
"(int (*)(char *, PyObject *)) "
+
from_py_func
tup
=
(
obj
.
result
(),
obj
.
result
(),
self
.
flags
,
self
.
ndim
,
to_py_func
,
from_py_func
)
return
(
"__pyx_memoryview_fromslice(&%s, %s.memview->obj, "
"%s, %s, %s, %s);"
%
tup
)
tup
=
(
obj
.
result
(),
self
.
ndim
,
to_py_func
,
from_py_func
)
return
"__pyx_memoryview_fromslice(&%s, %s, %s, %s);"
%
tup
def
dtype_object_conversion_funcs
(
self
,
env
):
import
MemoryView
,
Code
...
...
Cython/Compiler/Symtab.py
View file @
917cce5e
...
...
@@ -291,22 +291,21 @@ class Scope(object):
entries = [(name, entry)
for name, entry in other.entries.iteritems()
if entry.used or merge_unused]
# !@#$ py23
entries = dict(entries)
self.entries.update(entries)
for attr in ('const_entries',
'type_entries',
'sue_entries',
'arg_entries',
'var_entries',
'pyfunc_entries',
'cfunc_entries',
'c_class_entries'):
'type_entries',
'sue_entries',
'arg_entries',
'var_entries',
'pyfunc_entries',
'cfunc_entries',
'c_class_entries'):
self_entries = getattr(self, attr)
names = set([e.name for e in self_entries])
for entry in getattr(other, attr):
if
entry.used or merge_unused
:
if
(entry.used or merge_unused) and entry.name not in names
:
self_entries.append(entry)
def __str__(self):
...
...
Cython/Compiler/UtilityCode.py
View file @
917cce5e
...
...
@@ -115,8 +115,8 @@ class CythonUtilityCode(Code.UtilityCodeBase):
return
module_node
transform
=
ParseTreeTransforms
.
AnalyseDeclarationsTransform
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
transform
,
before
=
scope_
transform
)
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
scope_
transform
,
before
=
transform
)
(
err
,
tree
)
=
Pipeline
.
run_pipeline
(
pipeline
,
tree
)
assert
not
err
,
err
...
...
@@ -125,7 +125,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
def
put_code
(
self
,
output
):
pass
def
declare_in_scope
(
self
,
dest_scope
,
used
=
False
,
modname
=
None
):
def
declare_in_scope
(
self
,
dest_scope
,
used
=
False
):
"""
Declare all entries from the utility code in dest_scope. Code will only
be included for used entries. If module_name is given, declare the
...
...
@@ -143,13 +143,12 @@ class CythonUtilityCode(Code.UtilityCodeBase):
entry
.
utility_code_definition
=
self
entry
.
used
=
used
if
modname
and
entry
.
type
.
is_extension_type
:
entry
.
qualified_name
=
modname
entry
.
type
.
module_name
=
modname
dest_scope
.
merge_in
(
tree
.
scope
,
merge_unused
=
True
)
original_scope
=
tree
.
scope
dest_scope
.
merge_in
(
original_scope
,
merge_unused
=
True
)
tree
.
scope
=
dest_scope
for
dep
in
self
.
requires
:
if
dep
.
is_cython_utility
:
dep
.
declare_in_scope
(
dest_scope
)
return
original_scope
Cython/Utility/Buffer.c
View file @
917cce5e
...
...
@@ -35,19 +35,9 @@ static void __Pyx_RaiseBufferFallbackError(void) {
"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"
);
}
/////////////// BufferFormatCheck.proto ///////////////
{{
#
Buffer
format
string
checking
Buffer
type
checking
.
Utility
code
for
checking
that
acquired
buffers
match
our
assumptions
.
We
only
need
to
check
ndim
and
the
format
string
;
the
access
mode
/
flags
is
checked
by
the
exporter
.
The
alignment
code
is
copied
from
_struct
.
c
in
Python
.
}}
/////////////// BufferFormatStructs.proto ///////////////
#define IS_UNSIGNED(type) (((type) -1) > 0)
/* Run-time type information about structs used with buffers */
struct
__Pyx_StructField_
;
...
...
@@ -57,6 +47,7 @@ typedef struct {
struct
__Pyx_StructField_
*
fields
;
size_t
size
;
/* sizeof(type) */
char
typegroup
;
/* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
char
is_unsigned
;
}
__Pyx_TypeInfo
;
typedef
struct
__Pyx_StructField_
{
...
...
@@ -82,6 +73,19 @@ typedef struct {
}
__Pyx_BufFmt_Context
;
/////////////// BufferFormatCheck.proto ///////////////
{{
#
Buffer
format
string
checking
Buffer
type
checking
.
Utility
code
for
checking
that
acquired
buffers
match
our
assumptions
.
We
only
need
to
check
ndim
and
the
format
string
;
the
access
mode
/
flags
is
checked
by
the
exporter
.
The
alignment
code
is
copied
from
_struct
.
c
in
Python
.
}}
static
CYTHON_INLINE
int
__Pyx_GetBufferAndValidate
(
Py_buffer
*
buf
,
PyObject
*
obj
,
__Pyx_TypeInfo
*
dtype
,
int
flags
,
int
nd
,
int
cast
,
__Pyx_BufFmt_StackElem
*
stack
);
static
CYTHON_INLINE
void
__Pyx_SafeReleaseBuffer
(
Py_buffer
*
info
);
...
...
@@ -246,6 +250,7 @@ static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
}
}
static
void
__Pyx_BufFmt_RaiseExpected
(
__Pyx_BufFmt_Context
*
ctx
)
{
if
(
ctx
->
head
==
NULL
||
ctx
->
head
->
field
==
&
ctx
->
root
)
{
const
char
*
expected
;
...
...
@@ -519,3 +524,60 @@ static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
if
(
info
->
suboffsets
==
__Pyx_minusones
)
info
->
suboffsets
=
NULL
;
__Pyx_ReleaseBuffer
(
info
);
}
/////////////// TypeInfoToFormat.proto ///////////////
struct
__pyx_typeinfo_string
{
char
string
[
3
];
};
static
struct
__pyx_typeinfo_string
__Pyx_TypeInfoToFormat
(
__Pyx_TypeInfo
*
type
);
/////////////// TypeInfoToFormat ///////////////
{{
#
See
also
MemoryView
.
pyx
:
BufferFormatFromTypeInfo
}}
static
struct
__pyx_typeinfo_string
__Pyx_TypeInfoToFormat
(
__Pyx_TypeInfo
*
type
)
{
struct
__pyx_typeinfo_string
result
=
{
{
0
}
};
char
*
buf
=
(
char
*
)
result
.
string
;
size_t
size
=
type
->
size
;
switch
(
type
->
typegroup
)
{
case
'I'
:
case
'U'
:
if
(
size
==
1
)
*
buf
=
'c'
;
else
if
(
size
==
2
)
*
buf
=
'h'
;
else
if
(
size
==
4
)
*
buf
=
'i'
;
else
if
(
size
==
8
)
*
buf
=
'q'
;
if
(
type
->
is_unsigned
)
*
buf
=
toupper
(
*
buf
);
break
;
case
'P'
:
*
buf
=
'P'
;
break
;
case
'C'
:
{
__Pyx_TypeInfo
complex_type
=
*
type
;
complex_type
.
typegroup
=
'R'
;
complex_type
.
size
/=
2
;
*
buf
++
=
'Z'
;
/* Note: What about short/int/long complex? Probably not used? */
*
buf
=
__Pyx_TypeInfoToFormat
(
&
complex_type
).
string
[
0
];
break
;
}
case
'R'
:
if
(
size
==
4
)
*
buf
=
'f'
;
else
if
(
size
==
8
)
*
buf
=
'd'
;
else
*
buf
=
'g'
;
break
;
}
return
result
;
}
Cython/Utility/MemoryView.pyx
View file @
917cce5e
...
...
@@ -12,6 +12,10 @@ cdef extern from "Python.h":
PyBUF_ANY_CONTIGUOUS
PyBUF_FORMAT
void
Py_INCREF
(
object
)
void
Py_DECREF
(
object
)
cdef
extern
from
*
:
object
__pyx_memoryview_new
(
object
obj
,
int
flags
)
...
...
@@ -52,6 +56,8 @@ cdef class array:
self
.
strides
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
if
not
self
.
shape
or
not
self
.
strides
:
free
(
self
.
shape
)
free
(
self
.
strides
)
raise
MemoryError
(
"unable to allocate shape or strides."
)
cdef
int
idx
...
...
@@ -93,7 +99,6 @@ cdef class array:
raise
MemoryError
(
"unable to allocate array data."
)
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
cdef
int
bufmode
=
-
1
if
self
.
mode
==
b"c"
:
bufmode
=
PyBUF_C_CONTIGUOUS
|
PyBUF_ANY_CONTIGUOUS
...
...
@@ -114,27 +119,28 @@ cdef class array:
else
:
info
.
format
=
NULL
#
we do not need to call releasebuffer
info
.
obj
=
None
#
info.obj = self
# Py_INCREF(self)
def
__releasebuffer__
(
array
self
,
Py_buffer
*
info
):
# array.__releasebuffer__ should not be called,
# because the Py_buffer's 'obj' field is set to None.
raise
NotImplementedError
()
def
__releasebuffer__
(
self
,
Py_buffer
*
info
):
pass
def
__dealloc__
(
array
self
):
if
self
.
data
:
if
self
.
callback_free_data
!=
NULL
:
self
.
callback_free_data
(
self
.
data
)
else
:
free
(
self
.
data
)
self
.
data
=
NULL
if
self
.
callback_free_data
!=
NULL
:
self
.
callback_free_data
(
self
.
data
)
else
:
free
(
self
.
data
)
self
.
data
=
NULL
if
self
.
strides
:
free
(
self
.
strides
)
self
.
strides
=
NULL
if
self
.
shape
:
free
(
self
.
shape
)
self
.
shape
=
NULL
self
.
format
=
NULL
self
.
itemsize
=
0
...
...
@@ -148,8 +154,15 @@ cdef class array:
@
cname
(
"__pyx_array_new"
)
cdef
array
array_cwrapper
(
tuple
shape
,
Py_ssize_t
itemsize
,
char
*
format
,
char
*
mode
):
return
array
(
shape
,
itemsize
,
format
,
mode
.
decode
(
'ASCII'
))
cdef
array
array_cwrapper
(
tuple
shape
,
Py_ssize_t
itemsize
,
char
*
format
,
char
*
mode
,
char
*
buf
):
cdef
array
result
if
buf
==
NULL
:
result
=
array
(
shape
,
itemsize
,
format
,
mode
.
decode
(
'ASCII'
))
else
:
result
=
array
(
shape
,
itemsize
,
format
,
mode
.
decode
(
'ASCII'
),
allocate_buffer
=
False
)
result
.
data
=
buf
return
result
########## View.MemoryView ##########
...
...
@@ -169,14 +182,7 @@ cdef extern from *:
int
__Pyx_GetBuffer
(
object
,
Py_buffer
*
,
int
)
except
-
1
void
__Pyx_ReleaseBuffer
(
Py_buffer
*
)
ctypedef
struct
{{
memviewslice_name
}}:
char
*
data
Py_ssize_t
shape
[{{
max_dims
}}]
Py_ssize_t
strides
[{{
max_dims
}}]
Py_ssize_t
suboffsets
[{{
max_dims
}}]
void
puts
(
char
*
)
void
printf
(
char
*
,
...)
ctypedef
struct
PyObject
@
cname
(
'__pyx_MemviewEnum'
)
...
...
@@ -206,14 +212,18 @@ cdef class memoryview(object):
def
__cinit__
(
memoryview
self
,
object
obj
,
int
flags
):
self
.
obj
=
obj
__Pyx_GetBuffer
(
obj
,
&
self
.
view
,
flags
)
if
type
(
self
)
is
memoryview
or
obj
is
not
None
:
__Pyx_GetBuffer
(
obj
,
&
self
.
view
,
flags
)
self
.
lock
=
PyThread_allocate_lock
()
if
self
.
lock
==
NULL
:
raise
MemoryError
def
__dealloc__
(
memoryview
self
):
__Pyx_ReleaseBuffer
(
&
self
.
view
)
if
self
.
obj
is
not
None
:
__Pyx_ReleaseBuffer
(
&
self
.
view
)
if
self
.
lock
!=
NULL
:
PyThread_free_lock
(
self
.
lock
)
...
...
@@ -265,7 +275,11 @@ cdef class memoryview(object):
cdef
bytes
bytesitem
# Do a manual and complete check here instead of this easy hack
bytesitem
=
itemp
[:
self
.
view
.
itemsize
]
return
struct
.
unpack
(
self
.
view
.
format
,
bytesitem
)
result
=
struct
.
unpack
(
self
.
view
.
format
,
bytesitem
)
if
len
(
self
.
view
.
format
)
==
1
:
return
result
[
0
]
return
result
cdef
assign_item_from_object
(
self
,
char
*
itemp
,
object
value
):
"""Only used if instantiated manually by the user, or if Cython doesn't
...
...
@@ -283,11 +297,92 @@ cdef class memoryview(object):
for
i
,
c
in
enumerate
(
bytesvalue
):
itemp
[
i
]
=
c
property
_obj
:
@
cname
(
'__pyx_memoryview__get__obj'
)
def
__get__
(
self
):
if
(
self
.
obj
is
None
and
<
PyObject
*>
self
.
view
.
obj
!=
NULL
and
self
.
view
.
obj
is
not
None
):
return
<
object
>
self
.
view
.
obj
return
self
.
obj
def
__repr__
(
self
):
return
"<MemoryView of %r at 0x%x>"
%
(
self
.
obj
.
__class__
.
__name__
,
id
(
self
))
return
"<MemoryView of %r at 0x%x>"
%
(
self
.
_
obj
.
__class__
.
__name__
,
id
(
self
))
def
__str__
(
self
):
return
"<MemoryView of %r object>"
%
(
self
.
obj
.
__class__
.
__name__
,)
return
"<MemoryView of %r object>"
%
(
self
.
_obj
.
__class__
.
__name__
,)
@
cname
(
'__pyx_memoryview_new'
)
cdef
memoryview_cwrapper
(
object
o
,
int
flags
):
return
memoryview
(
o
,
flags
)
cdef
_check_index
(
index
):
if
not
PyIndex_Check
(
index
):
raise
TypeError
(
"Cannot index with %s"
%
type
(
index
))
cdef
tuple
_unellipsify
(
tuple
tup
,
int
ndim
):
if
Ellipsis
in
tup
:
result
=
[]
for
idx
,
item
in
enumerate
(
tup
):
if
item
is
Ellipsis
:
result
.
extend
([
slice
(
None
)]
*
(
ndim
-
len
(
tup
)
+
1
))
result
.
extend
(
tup
[
idx
+
1
:])
break
result
.
append
(
item
)
return
tuple
(
result
)
return
tup
@
cname
(
'__pyx_pybuffer_index'
)
cdef
char
*
pybuffer_index
(
Py_buffer
*
view
,
char
*
bufp
,
Py_ssize_t
index
,
int
dim
)
except
NULL
:
cdef
Py_ssize_t
shape
,
stride
,
suboffset
=
-
1
cdef
Py_ssize_t
itemsize
=
view
.
itemsize
cdef
char
*
resultp
if
view
.
ndim
==
0
:
shape
=
view
.
len
/
itemsize
stride
=
itemsize
else
:
shape
=
view
.
shape
[
dim
]
stride
=
view
.
strides
[
dim
]
if
view
.
suboffsets
!=
NULL
:
suboffset
=
view
.
suboffsets
[
dim
]
if
index
<
0
:
index
+=
view
.
shape
[
dim
]
if
index
<
0
:
raise
IndexError
(
"Out of bounds on buffer access (axis %d)"
%
dim
)
if
index
>=
shape
:
raise
IndexError
(
"Out of bounds on buffer access (axis %d)"
%
dim
)
resultp
=
bufp
+
index
*
stride
if
suboffset
>=
0
:
resultp
=
(
<
char
**>
resultp
)[
0
]
+
suboffset
return
resultp
############### MemviewFromSlice ###############
cdef
extern
from
*
:
cdef
struct
__pyx_memoryview
:
Py_buffer
view
PyObject
*
obj
ctypedef
struct
{{
memviewslice_name
}}:
__pyx_memoryview
*
memview
char
*
data
Py_ssize_t
shape
[{{
max_dims
}}]
Py_ssize_t
strides
[{{
max_dims
}}]
Py_ssize_t
suboffsets
[{{
max_dims
}}]
void
__PYX_INC_MEMVIEW
({{
memviewslice_name
}}
*
memslice
,
int
have_gil
)
void
__PYX_XDEC_MEMVIEW
({{
memviewslice_name
}}
*
memslice
,
int
have_gil
)
@
cname
(
'__pyx_memoryviewslice'
)
...
...
@@ -296,17 +391,14 @@ cdef class _memoryviewslice(memoryview):
# We need this to keep our shape/strides/suboffset pointers valid
cdef
{{
memviewslice_name
}}
from_slice
#
Restore the original Py_buffer before releasing
cdef
Py_buffer
orig_view
#
We need this only to print it's classes name
cdef
object
from_object
cdef
object
(
*
to_object_func
)(
char
*
)
cdef
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
def
__cinit__
(
self
,
object
obj
,
int
flags
):
self
.
orig_view
=
self
.
view
def
__dealloc__
(
self
):
self
.
view
=
self
.
orig_view
__PYX_XDEC_MEMVIEW
(
&
self
.
from_slice
,
1
)
cdef
convert_item_to_object
(
self
,
char
*
itemp
):
if
self
.
to_object_func
!=
NULL
:
...
...
@@ -320,21 +412,29 @@ cdef class _memoryviewslice(memoryview):
else
:
memoryview
.
assign_item_from_object
(
self
,
itemp
,
value
)
property
_obj
:
@
cname
(
'__pyx_memoryviewslice__get__obj'
)
def
__get__
(
self
):
return
self
.
from_object
@
cname
(
'__pyx_memoryview_new'
)
cdef
memoryview_cwrapper
(
object
o
,
int
flags
):
return
memoryview
(
o
,
flags
)
@
cname
(
'__pyx_memoryview_fromslice'
)
cdef
memoryview_from_memslice_cwrapper
(
{{
memviewslice_name
}}
*
memviewslice
,
object
orig_obj
,
int
flags
,
int
cur_ndim
,
{{
memviewslice_name
}}
*
memviewslice
,
int
cur_ndim
,
object
(
*
to_object_func
)(
char
*
),
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
):
cdef
_memoryviewslice
result
=
_memoryviewslice
(
orig_obj
,
flags
)
cdef
int
new_ndim
=
result
.
view
.
ndim
-
cur_ndim
assert
0
<
cur_ndim
<=
memviewslice
.
memview
.
view
.
ndim
cdef
_memoryviewslice
result
=
_memoryviewslice
(
None
,
0
)
cdef
int
new_ndim
=
memviewslice
.
memview
.
view
.
ndim
-
cur_ndim
result
.
from_slice
=
memviewslice
[
0
]
__PYX_INC_MEMVIEW
(
memviewslice
,
1
)
result
.
from_object
=
<
object
>
memviewslice
.
memview
.
obj
result
.
view
=
memviewslice
.
memview
.
view
result
.
view
.
shape
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
shape
+
new_ndim
)
result
.
view
.
strides
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
strides
+
new_ndim
)
result
.
view
.
suboffsets
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
suboffsets
+
new_ndim
)
...
...
@@ -345,51 +445,55 @@ cdef memoryview_from_memslice_cwrapper(
return
result
cdef
_check_index
(
index
):
if
not
PyIndex_Check
(
index
)
:
raise
TypeError
(
"Cannot index with %s"
%
type
(
index
))
############### BufferFormatFromTypeInfo ###############
cdef
extern
from
*
:
ctypedef
struct
__Pyx_StructField
cdef
tuple
_unellipsify
(
tuple
tup
,
int
ndim
):
if
Ellipsis
in
tup
:
result
=
[]
for
idx
,
item
in
enumerate
(
tup
):
if
item
is
Ellipsis
:
result
.
extend
([
slice
(
None
)]
*
(
ndim
-
len
(
tup
)
+
1
))
result
.
extend
(
tup
[
idx
+
1
:])
break
ctypedef
struct
__Pyx_TypeInfo
:
char
*
name
__Pyx_StructField
*
fields
size_t
size
char
typegroup
char
is_unsigned
result
.
append
(
item
)
ctypedef
struct
__Pyx_StructField
:
__Pyx_TypeInfo
*
type
char
*
name
size_t
offset
return
tuple
(
result
)
ctypedef
struct
__Pyx_BufFmt_StackElem
:
__Pyx_StructField
*
field
size_t
parent_offset
return
tup
#ctypedef struct __Pyx_BufFmt_Context:
# __Pyx_StructField root
__Pyx_BufFmt_StackElem
*
head
@
cname
(
'__pyx_pybuffer_index'
)
cdef
char
*
pybuffer_index
(
Py_buffer
*
view
,
char
*
bufp
,
Py_ssize_t
index
,
int
dim
)
except
NULL
:
cdef
Py_ssize_t
shape
,
stride
,
suboffset
=
-
1
cdef
Py_ssize_t
itemsize
=
view
.
itemsize
cdef
char
*
resultp
struct
__pyx_typeinfo_string
:
char
string
[
3
]
if
view
.
ndim
==
0
:
shape
=
view
.
len
/
itemsize
stride
=
itemsize
else
:
shape
=
view
.
shape
[
dim
]
stride
=
view
.
strides
[
dim
]
if
view
.
suboffsets
!=
NULL
:
suboffset
=
view
.
suboffsets
[
dim
]
__pyx_typeinfo_string
__Pyx_TypeInfoToFormat
(
__Pyx_TypeInfo
*
)
if
index
<
0
:
index
+=
view
.
shape
[
dim
]
if
index
<
0
:
raise
IndexError
(
"Out of bounds on buffer access (axis %d)"
%
dim
)
if
index
>=
shape
:
raise
IndexError
(
"Out of bounds on buffer access (axis %d)"
%
dim
)
@
cname
(
'__pyx_format_from_typeinfo'
)
cdef
format_from_typeinfo
(
__Pyx_TypeInfo
*
type
):
cdef
__Pyx_StructField
*
field
cdef
__pyx_typeinfo_string
fmt
resultp
=
bufp
+
index
*
stride
if
suboffset
>=
0
:
resultp
=
(
<
char
**>
resultp
)[
0
]
+
suboffset
if
type
.
typegroup
==
'S'
:
assert
type
.
fields
!=
NULL
and
type
.
fields
.
type
!=
NULL
return
resultp
parts
=
[
"T{"
]
field
=
type
.
fields
while
field
.
type
:
parts
.
append
(
format_from_typeinfo
(
field
.
type
))
field
+=
1
parts
.
append
(
"}"
)
result
=
""
.
join
(
parts
)
else
:
fmt
=
__Pyx_TypeInfoToFormat
(
type
)
result
=
fmt
.
string
return
result
Cython/Utility/MemoryView_C.c
View file @
917cce5e
...
...
@@ -56,9 +56,8 @@ static CYTHON_INLINE char *__pyx_memviewslice_index_full(const char *bufp, Py_ss
{{
#
__Pyx_PyObject_to_MemoryviewSlice_
<
count
>
}}
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
obj
)
{
{{
memviewslice_name
}}
result
;
result
.
memview
=
NULL
;
result
.
data
=
NULL
;
{{
memviewslice_name
}}
result
=
{
0
};
struct
__pyx_memoryview_obj
*
memview
=
\
(
struct
__pyx_memoryview_obj
*
)
__pyx_memoryview_new
(
obj
,
{{
buf_flag
}});
__Pyx_BufFmt_StackElem
stack
[{{
struct_nesting_depth
}}];
...
...
@@ -294,9 +293,9 @@ static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
memview
->
acquisition_count
,
lineno
);
//
PyThread_acquire_lock(memview->lock, 1);
PyThread_acquire_lock
(
memview
->
lock
,
1
);
first_time
=
(
memview
->
acquisition_count
++
==
0
);
//
PyThread_release_lock(memview->lock);
PyThread_release_lock
(
memview
->
lock
);
if
(
first_time
)
{
if
(
have_gil
)
{
...
...
@@ -321,9 +320,9 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
memview
->
acquisition_count
,
lineno
);
//
PyThread_acquire_lock(memview->lock, 1);
PyThread_acquire_lock
(
memview
->
lock
,
1
);
last_time
=
(
memview
->
acquisition_count
--
==
1
);
//
PyThread_release_lock(memview->lock);
PyThread_release_lock
(
memview
->
lock
);
if
(
last_time
)
{
if
(
have_gil
)
{
...
...
@@ -370,7 +369,7 @@ static __Pyx_memviewslice {{copy_name}}(const __Pyx_memviewslice from_mvs) {
}
}
array_obj
=
__pyx_array_new
(
shape_tuple
,
{{
sizeof_dtype
}},
buf
->
format
,
mode
);
array_obj
=
__pyx_array_new
(
shape_tuple
,
{{
sizeof_dtype
}},
buf
->
format
,
mode
,
NULL
);
if
(
unlikely
(
!
array_obj
))
{
goto
fail
;
}
...
...
@@ -412,12 +411,15 @@ no_fail:
/////////////// MemviewSliceIndex ///////////////
static
CYTHON_INLINE
char
*
__pyx_memviewslice_index_full
(
const
char
*
bufp
,
Py_ssize_t
idx
,
Py_ssize_t
stride
,
Py_ssize_t
suboffset
)
{
static
CYTHON_INLINE
char
*
__pyx_memviewslice_index_full
(
const
char
*
bufp
,
Py_ssize_t
idx
,
Py_ssize_t
stride
,
Py_ssize_t
suboffset
)
{
bufp
=
bufp
+
idx
*
stride
;
if
(
suboffset
>=
0
)
{
bufp
=
*
((
char
**
)
bufp
)
+
suboffset
;
}
return
bufp
;
return
(
char
*
)
bufp
;
}
/////////////// MemviewDtypeToObject.proto ///////////////
...
...
tests/run/cythonarray.pyx
View file @
917cce5e
...
...
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
from
cython
cimport
array
cimport
cython
as
cy
from
libc.stdlib
cimport
malloc
,
free
def
contiguity
():
'''
>>> contiguity()
...
...
@@ -85,19 +87,79 @@ cdef create_array(shape, mode):
return
result
def
test_cython_array
():
def
test_cython_array
_getbuffer
():
"""
>>> test_cython_array()
>>> test_cython_array
_getbuffer
()
98
61
98
61
"""
cdef
int
[:,
::
1
]
carr
=
create_array
((
14
,
10
),
'c'
)
cdef
int
[::
1
,
:]
farr
=
create_array
((
14
,
10
),
'fortran'
)
cdef
int
[:,
::
1
]
cslice
=
create_array
((
14
,
10
),
'c'
)
cdef
int
[::
1
,
:]
fslice
=
create_array
((
14
,
10
),
'fortran'
)
print
cslice
[
9
,
8
]
print
cslice
[
6
,
1
]
print
fslice
[
9
,
8
]
print
fslice
[
6
,
1
]
def
test_cython_array_index
():
"""
>>> test_cython_array_index()
98
61
98
61
"""
c_array
=
create_array
((
14
,
10
),
'c'
)
f_array
=
create_array
((
14
,
10
),
'fortran'
)
print
c_array
[
9
,
8
]
print
c_array
[
6
,
1
]
print
f_array
[
9
,
8
]
print
f_array
[
6
,
1
]
cdef
int
*
getp
(
int
dim1
=
10
,
int
dim2
=
10
)
except
NULL
:
print
"getp()"
cdef
int
*
p
=
<
int
*>
malloc
(
dim1
*
dim2
*
sizeof
(
int
))
if
p
==
NULL
:
raise
MemoryError
for
i
in
range
(
dim1
*
dim2
):
p
[
i
]
=
i
return
p
cdef
void
callback_free_data
(
char
*
p
):
print
'callback free data called'
free
(
p
)
def
test_array_from_pointer
():
"""
>>> test_array_from_pointer()
getp()
69
c
getp()
fortran
getp()
56
getp()
56
callback free data called
"""
cdef
int
*
p
=
getp
()
cdef
array
c_arr
=
<
int
[:
10
,
:
10
]
>
p
c_arr
.
callback_free_data
=
callback_free_data
print
c_arr
[
6
,
9
]
print
c_arr
.
mode
print
carr
[
9
,
8
]
print
carr
[
6
,
1
]
print
(
<
int
[:
10
:
1
,
:
10
]
>
getp
()).
mode
print
farr
[
9
,
8
]
print
farr
[
6
,
1
]
cdef
int
[:,
::
1
]
mslice
=
<
int
[:
10
,
:
10
]
>
getp
()
print
mslice
[
5
,
6
]
print
(
<
int
[:
12
,
:
10
]
>
getp
(
12
,
10
))[
5
,
6
]
tests/run/memoryview.pyx
View file @
917cce5e
...
...
@@ -219,28 +219,20 @@ def get_int_2d(int[:, :] mslice, int i, int j):
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> get_int_2d(C, 1, 1)
acquired C
acquired C
released C
released C
4
Check negative indexing:
>>> get_int_2d(C, -1, 0)
acquired C
acquired C
released C
released C
3
>>> get_int_2d(C, -1, -2)
acquired C
acquired C
released C
released C
4
>>> get_int_2d(C, -2, -3)
acquired C
acquired C
released C
released C
0
...
...
@@ -265,50 +257,34 @@ def set_int_2d(int[:, :] mslice, int i, int j, int value):
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> set_int_2d(C, 1, 1, 10)
acquired C
acquired C
released C
released C
>>> get_int_2d(C, 1, 1)
acquired C
acquired C
released C
released C
10
Check negative indexing:
>>> set_int_2d(C, -1, 0, 3)
acquired C
acquired C
released C
released C
>>> get_int_2d(C, -1, 0)
acquired C
acquired C
released C
released C
3
>>> set_int_2d(C, -1, -2, 8)
acquired C
acquired C
released C
released C
>>> get_int_2d(C, -1, -2)
acquired C
acquired C
released C
released C
8
>>> set_int_2d(C, -2, -3, 9)
acquired C
acquired C
released C
released C
>>> get_int_2d(C, -2, -3)
acquired C
acquired C
released C
released C
9
...
...
@@ -336,8 +312,6 @@ def writable(unsigned short int[:, :, :] mslice):
>>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3))
>>> writable(R)
acquired R
acquired R
released R
released R
>>> [str(x) for x in R.recieved_flags] # Py2/3
['FORMAT', 'ND', 'STRIDES', 'WRITABLE']
...
...
@@ -350,8 +324,6 @@ def strided(int[:] mslice):
>>> A = IntMockBuffer("A", range(4))
>>> strided(A)
acquired A
acquired A
released A
released A
2
...
...
@@ -410,16 +382,12 @@ def generic(int[::view.generic, ::view.generic] mslice1,
>>> generic(A, B)
acquired A
acquired B
acquired A
acquired B
4
4
10
11
released A
released B
released A
released B
"""
buf1
,
buf2
=
mslice1
,
mslice2
...
...
@@ -440,16 +408,12 @@ def generic_contig(int[::view.generic_contiguous, :] mslice1,
>>> generic_contig(A, B)
acquired A
acquired B
acquired A
acquired B
4
4
10
11
released A
released B
released A
released B
"""
buf1
,
buf2
=
mslice1
,
mslice2
...
...
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