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
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 *
...
@@ -5,7 +5,7 @@ from ExprNodes import *
from
StringEncoding
import
EncodedString
from
StringEncoding
import
EncodedString
from
Errors
import
CompileError
from
Errors
import
CompileError
from
UtilityCode
import
CythonUtilityCode
from
UtilityCode
import
CythonUtilityCode
from
Code
import
UtilityCode
from
Code
import
UtilityCode
,
ContentHashingUtilityCode
import
Cython.Compiler.Options
import
Cython.Compiler.Options
import
Interpreter
import
Interpreter
import
PyrexTypes
import
PyrexTypes
...
@@ -34,10 +34,11 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
...
@@ -34,10 +34,11 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
assert
isinstance
(
node
,
ModuleNode
)
assert
isinstance
(
node
,
ModuleNode
)
self
.
max_ndim
=
0
self
.
max_ndim
=
0
result
=
super
(
IntroduceBufferAuxiliaryVars
,
self
).
__call__
(
node
)
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_bufstruct_declare_code
(
node
.
scope
)
use_py2_buffer_functions
(
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
return
result
...
@@ -476,13 +477,15 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives,
...
@@ -476,13 +477,15 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives,
def
use_bufstruct_declare_code
(
env
):
def
use_bufstruct_declare_code
(
env
):
env
.
use_utility_code
(
buffer_struct_declare_code
)
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
(
"""
code
=
dedent
(
"""
Py_ssize_t __Pyx_zeros[] = {%s};
Py_ssize_t __Pyx_zeros[] = {%s};
Py_ssize_t __Pyx_minusones[] = {%s};
Py_ssize_t __Pyx_minusones[] = {%s};
"""
)
%
(
", "
.
join
([
"0"
]
*
max_ndim
),
", "
.
join
([
"-1"
]
*
max_ndim
))
"""
)
%
(
", "
.
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
):
def
buf_lookup_full_code
(
proto
,
defin
,
name
,
nd
):
"""
"""
...
@@ -725,12 +728,18 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -725,12 +728,18 @@ def get_type_information_cname(code, dtype, maxdepth=None):
print
dtype
print
dtype
assert
False
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
,
)
%
(
name
,
rep
,
rep
,
structinfo_name
,
structinfo_name
,
declcode
,
declcode
,
typegroup
,
typegroup
,
is_unsigned
,
),
safe
=
True
)
),
safe
=
True
)
return
name
return
name
...
@@ -753,5 +762,11 @@ impl = """
...
@@ -753,5 +762,11 @@ impl = """
"""
)
"""
)
raise_buffer_fallback_code
=
load_buffer_utility
(
"BufferFallbackError"
)
raise_buffer_fallback_code
=
load_buffer_utility
(
"BufferFallbackError"
)
buffer_structs_code
=
load_buffer_utility
(
"BufferFormatStructs"
)
acquire_utility_code
=
load_buffer_utility
(
"BufferFormatCheck"
,
acquire_utility_code
=
load_buffer_utility
(
"BufferFormatCheck"
,
context
=
context
)
context
=
context
,
\ No newline at end of file
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):
...
@@ -318,7 +318,12 @@ class ContentHashingUtilityCode(UtilityCode):
return
hash
((
self
.
proto
,
self
.
impl
))
return
hash
((
self
.
proto
,
self
.
impl
))
def
__eq__
(
self
,
other
):
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
):
class
LazyUtilityCode
(
UtilityCodeBase
):
...
...
Cython/Compiler/CythonScope.py
View file @
917cce5e
...
@@ -71,12 +71,14 @@ class CythonScope(ModuleScope):
...
@@ -71,12 +71,14 @@ class CythonScope(ModuleScope):
# self.test_cythonscope()
# self.test_cythonscope()
def
test_cythonscope
(
self
):
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
Creates some entries for testing purposes and entries for
# "end-users" but nobody will know it is there anyway...
cython.array() and for cython.view.*.
"""
cython_testscope_utility_code
.
declare_in_scope
(
self
)
cython_testscope_utility_code
.
declare_in_scope
(
self
)
cython_test_extclass_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
# The view sub-scope
...
@@ -92,7 +94,9 @@ class CythonScope(ModuleScope):
...
@@ -92,7 +94,9 @@ class CythonScope(ModuleScope):
cythonview_testscope_utility_code
.
declare_in_scope
(
viewscope
)
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
):
def
create_cython_scope
(
context
,
create_testscope
):
...
@@ -132,15 +136,4 @@ cython_test_extclass_utility_code = \
...
@@ -132,15 +136,4 @@ cython_test_extclass_utility_code = \
requires
=
[
undecorated_methods_protos
,
requires
=
[
undecorated_methods_protos
,
test_cython_utility_dep
])
test_cython_utility_dep
])
cythonview_testscope_utility_code
=
load_testscope_utility
(
"View.TestScope"
)
cythonview_testscope_utility_code
=
load_testscope_utility
(
"View.TestScope"
)
\ No newline at end of file
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
])
Cython/Compiler/ExprNodes.py
View file @
917cce5e
...
@@ -584,6 +584,11 @@ class ExprNode(Node):
...
@@ -584,6 +584,11 @@ class ExprNode(Node):
if
dst_type
.
is_reference
:
if
dst_type
.
is_reference
:
dst_type
=
dst_type
.
ref_base_type
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
:
if
dst_type
.
is_memoryviewslice
:
import
MemoryView
import
MemoryView
if
not
src
.
type
.
is_memoryviewslice
:
if
not
src
.
type
.
is_memoryviewslice
:
...
@@ -747,6 +752,7 @@ class PyConstNode(AtomicExprNode):
...
@@ -747,6 +752,7 @@ class PyConstNode(AtomicExprNode):
class
NoneNode
(
PyConstNode
):
class
NoneNode
(
PyConstNode
):
# The constant value None
# The constant value None
is_none
=
1
value
=
"Py_None"
value
=
"Py_None"
constant_result
=
None
constant_result
=
None
...
@@ -6051,6 +6057,157 @@ class TypecastNode(ExprNode):
...
@@ -6051,6 +6057,157 @@ class TypecastNode(ExprNode):
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
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
):
class
SizeofNode
(
ExprNode
):
# Abstract base class for sizeof(x) expression nodes.
# Abstract base class for sizeof(x) expression nodes.
...
@@ -7910,6 +8067,10 @@ class CoerceToPyTypeNode(CoercionNode):
...
@@ -7910,6 +8067,10 @@ class CoerceToPyTypeNode(CoercionNode):
# FIXME: check that the target type and the resulting type are compatible
# FIXME: check that the target type and the resulting type are compatible
pass
pass
if
arg
.
type
.
is_memoryviewslice
:
# Register utility codes at this point
arg
.
type
.
get_to_py_function
(
env
,
arg
)
self
.
env
=
env
self
.
env
=
env
gil_message
=
"Converting to Python object"
gil_message
=
"Converting to Python object"
...
...
Cython/Compiler/MemoryView.py
View file @
917cce5e
...
@@ -66,8 +66,6 @@ memview_typeptr_cname = '__pyx_memoryview_type'
...
@@ -66,8 +66,6 @@ memview_typeptr_cname = '__pyx_memoryview_type'
memview_objstruct_cname
=
'__pyx_memoryview_obj'
memview_objstruct_cname
=
'__pyx_memoryview_obj'
memviewslice_cname
=
u'__Pyx_memviewslice'
memviewslice_cname
=
u'__Pyx_memviewslice'
def
put_init_entry
(
mv_cname
,
code
):
def
put_init_entry
(
mv_cname
,
code
):
code
.
putln
(
"%s.data = NULL;"
%
mv_cname
)
code
.
putln
(
"%s.data = NULL;"
%
mv_cname
)
code
.
putln
(
"%s.memview = NULL;"
%
mv_cname
)
code
.
putln
(
"%s.memview = NULL;"
%
mv_cname
)
...
@@ -129,18 +127,9 @@ def get_buf_flags(specs):
...
@@ -129,18 +127,9 @@ def get_buf_flags(specs):
else
:
else
:
return
memview_strided_access
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
):
def
use_cython_array
(
env
):
import
CythonScope
env
.
use_utility_code
(
cython_array_utility_code
)
env
.
use_utility_code
(
CythonScope
.
cython_array_utility_code
)
def
src_conforms_to_dst
(
src
,
dst
):
def
src_conforms_to_dst
(
src
,
dst
):
'''
'''
...
@@ -778,7 +767,31 @@ memviewslice_declare_code = load_memview_c_utility(
...
@@ -778,7 +767,31 @@ memviewslice_declare_code = load_memview_c_utility(
memviewslice_init_code
=
load_memview_c_utility
(
memviewslice_init_code
=
load_memview_c_utility
(
"MemviewSliceInit"
,
"MemviewSliceInit"
,
context
=
dict
(
context
,
BUF_MAX_NDIMS
=
Options
.
buffer_max_dims
),
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"
)
cython_array_utility_code
=
load_memview_cy_utility
(
\ No newline at end of file
"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):
...
@@ -2440,8 +2440,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type
.
typeptr_cname
,
type
.
typeobj_cname
))
type
.
typeptr_cname
,
type
.
typeobj_cname
))
def
generate_cfunction_declaration
(
entry
,
env
,
code
,
definition
):
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
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'
:
if
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
dll_linkage
=
"DL_IMPORT"
...
...
Cython/Compiler/Nodes.py
View file @
917cce5e
...
@@ -126,6 +126,7 @@ class Node(object):
...
@@ -126,6 +126,7 @@ class Node(object):
__metaclass__
=
VerboseCodeWriter
__metaclass__
=
VerboseCodeWriter
is_name
=
0
is_name
=
0
is_none
=
0
is_literal
=
0
is_literal
=
0
is_terminator
=
0
is_terminator
=
0
temps
=
None
temps
=
None
...
@@ -137,6 +138,11 @@ class Node(object):
...
@@ -137,6 +138,11 @@ class Node(object):
cf_state
=
None
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
):
def
__init__
(
self
,
pos
,
**
kw
):
self
.
pos
=
pos
self
.
pos
=
pos
...
@@ -823,12 +829,18 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
...
@@ -823,12 +829,18 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
return
self
.
type
return
self
.
type
self
.
type
=
PyrexTypes
.
MemoryViewSliceType
(
base_type
,
axes_specs
)
self
.
type
=
PyrexTypes
.
MemoryViewSliceType
(
base_type
,
axes_specs
)
MemoryView
.
use_memview_util_code
(
env
)
if
self
.
type
.
dtype
.
is_memoryviewslice
:
MemoryView
.
use_cython_array
(
env
)
error
(
self
.
pos
,
"Memoryview slices may not be used as the "
MemoryView
.
use_memview_util_code
(
env
)
"base type for memoryview slices"
)
env
.
use_utility_code
(
MemoryView
.
memviewslice_declare_code
)
self
.
use_memview_utilities
(
env
)
return
self
.
type
return
self
.
type
def
use_memview_utilities
(
self
,
env
):
import
MemoryView
env
.
use_utility_code
(
MemoryView
.
view_utility_code
)
class
CNestedBaseTypeNode
(
CBaseTypeNode
):
class
CNestedBaseTypeNode
(
CBaseTypeNode
):
# For C++ classes that live inside other C++ classes.
# For C++ classes that live inside other C++ classes.
...
...
Cython/Compiler/Parsing.py
View file @
917cce5e
...
@@ -297,7 +297,8 @@ def p_typecast(s):
...
@@ -297,7 +297,8 @@ def p_typecast(s):
pos
=
s
.
position
()
pos
=
s
.
position
()
s
.
next
()
s
.
next
()
base_type
=
p_c_base_type
(
s
)
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"
)
s
.
error
(
"Unknown type"
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
if
s
.
sy
==
'?'
:
if
s
.
sy
==
'?'
:
...
@@ -307,6 +308,10 @@ def p_typecast(s):
...
@@ -307,6 +308,10 @@ def p_typecast(s):
typecheck
=
0
typecheck
=
0
s
.
expect
(
">"
)
s
.
expect
(
">"
)
operand
=
p_factor
(
s
)
operand
=
p_factor
(
s
)
if
is_memslice
:
return
ExprNodes
.
CythonArrayNode
(
pos
,
base_type_node
=
base_type
,
operand
=
operand
)
return
ExprNodes
.
TypecastNode
(
pos
,
return
ExprNodes
.
TypecastNode
(
pos
,
base_type
=
base_type
,
base_type
=
base_type
,
declarator
=
declarator
,
declarator
=
declarator
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
917cce5e
...
@@ -553,14 +553,15 @@ class MemoryViewSliceType(PyrexType):
...
@@ -553,14 +553,15 @@ class MemoryViewSliceType(PyrexType):
return
True
return
True
def
get_to_py_function
(
self
,
env
,
obj
):
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
,
from_py_func
=
self
.
dtype_object_conversion_funcs
(
env
)
to_py_func
=
"(PyObject *(*)(char *)) "
+
to_py_func
to_py_func
=
"(PyObject *(*)(char *)) "
+
to_py_func
from_py_func
=
"(int (*)(char *, PyObject *)) "
+
from_py_func
from_py_func
=
"(int (*)(char *, PyObject *)) "
+
from_py_func
tup
=
(
obj
.
result
(),
obj
.
result
(),
self
.
flags
,
self
.
ndim
,
tup
=
(
obj
.
result
(),
self
.
ndim
,
to_py_func
,
from_py_func
)
to_py_func
,
from_py_func
)
return
"__pyx_memoryview_fromslice(&%s, %s, %s, %s);"
%
tup
return
(
"__pyx_memoryview_fromslice(&%s, %s.memview->obj, "
"%s, %s, %s, %s);"
%
tup
)
def
dtype_object_conversion_funcs
(
self
,
env
):
def
dtype_object_conversion_funcs
(
self
,
env
):
import
MemoryView
,
Code
import
MemoryView
,
Code
...
...
Cython/Compiler/Symtab.py
View file @
917cce5e
...
@@ -291,22 +291,21 @@ class Scope(object):
...
@@ -291,22 +291,21 @@ class Scope(object):
entries = [(name, entry)
entries = [(name, entry)
for name, entry in other.entries.iteritems()
for name, entry in other.entries.iteritems()
if entry.used or merge_unused]
if entry.used or merge_unused]
# !@#$ py23
entries = dict(entries)
self.entries.update(entries)
self.entries.update(entries)
for attr in ('const_entries',
for attr in ('const_entries',
'type_entries',
'type_entries',
'sue_entries',
'sue_entries',
'arg_entries',
'arg_entries',
'var_entries',
'var_entries',
'pyfunc_entries',
'pyfunc_entries',
'cfunc_entries',
'cfunc_entries',
'c_class_entries'):
'c_class_entries'):
self_entries = getattr(self, attr)
self_entries = getattr(self, attr)
names = set([e.name for e in self_entries])
for entry in getattr(other, attr):
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)
self_entries.append(entry)
def __str__(self):
def __str__(self):
...
...
Cython/Compiler/UtilityCode.py
View file @
917cce5e
...
@@ -115,8 +115,8 @@ class CythonUtilityCode(Code.UtilityCodeBase):
...
@@ -115,8 +115,8 @@ class CythonUtilityCode(Code.UtilityCodeBase):
return
module_node
return
module_node
transform
=
ParseTreeTransforms
.
AnalyseDeclarationsTransform
transform
=
ParseTreeTransforms
.
AnalyseDeclarationsTransform
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
transform
,
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
scope_
transform
,
before
=
scope_
transform
)
before
=
transform
)
(
err
,
tree
)
=
Pipeline
.
run_pipeline
(
pipeline
,
tree
)
(
err
,
tree
)
=
Pipeline
.
run_pipeline
(
pipeline
,
tree
)
assert
not
err
,
err
assert
not
err
,
err
...
@@ -125,7 +125,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
...
@@ -125,7 +125,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
def
put_code
(
self
,
output
):
def
put_code
(
self
,
output
):
pass
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
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
be included for used entries. If module_name is given, declare the
...
@@ -143,13 +143,12 @@ class CythonUtilityCode(Code.UtilityCodeBase):
...
@@ -143,13 +143,12 @@ class CythonUtilityCode(Code.UtilityCodeBase):
entry
.
utility_code_definition
=
self
entry
.
utility_code_definition
=
self
entry
.
used
=
used
entry
.
used
=
used
if
modname
and
entry
.
type
.
is_extension_type
:
original_scope
=
tree
.
scope
entry
.
qualified_name
=
modname
dest_scope
.
merge_in
(
original_scope
,
merge_unused
=
True
)
entry
.
type
.
module_name
=
modname
dest_scope
.
merge_in
(
tree
.
scope
,
merge_unused
=
True
)
tree
.
scope
=
dest_scope
tree
.
scope
=
dest_scope
for
dep
in
self
.
requires
:
for
dep
in
self
.
requires
:
if
dep
.
is_cython_utility
:
if
dep
.
is_cython_utility
:
dep
.
declare_in_scope
(
dest_scope
)
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) {
...
@@ -35,19 +35,9 @@ static void __Pyx_RaiseBufferFallbackError(void) {
"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"
);
"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"
);
}
}
/////////////// BufferFormatCheck.proto ///////////////
/////////////// BufferFormatStructs.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
.
}}
#define IS_UNSIGNED(type) (((type) -1) > 0)
/* Run-time type information about structs used with buffers */
/* Run-time type information about structs used with buffers */
struct
__Pyx_StructField_
;
struct
__Pyx_StructField_
;
...
@@ -57,6 +47,7 @@ typedef struct {
...
@@ -57,6 +47,7 @@ typedef struct {
struct
__Pyx_StructField_
*
fields
;
struct
__Pyx_StructField_
*
fields
;
size_t
size
;
/* sizeof(type) */
size_t
size
;
/* sizeof(type) */
char
typegroup
;
/* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
char
typegroup
;
/* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
char
is_unsigned
;
}
__Pyx_TypeInfo
;
}
__Pyx_TypeInfo
;
typedef
struct
__Pyx_StructField_
{
typedef
struct
__Pyx_StructField_
{
...
@@ -82,6 +73,19 @@ typedef struct {
...
@@ -82,6 +73,19 @@ typedef struct {
}
__Pyx_BufFmt_Context
;
}
__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
,
static
CYTHON_INLINE
int
__Pyx_GetBufferAndValidate
(
Py_buffer
*
buf
,
PyObject
*
obj
,
__Pyx_TypeInfo
*
dtype
,
int
flags
,
int
nd
,
int
cast
,
__Pyx_BufFmt_StackElem
*
stack
);
__Pyx_TypeInfo
*
dtype
,
int
flags
,
int
nd
,
int
cast
,
__Pyx_BufFmt_StackElem
*
stack
);
static
CYTHON_INLINE
void
__Pyx_SafeReleaseBuffer
(
Py_buffer
*
info
);
static
CYTHON_INLINE
void
__Pyx_SafeReleaseBuffer
(
Py_buffer
*
info
);
...
@@ -246,6 +250,7 @@ static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
...
@@ -246,6 +250,7 @@ static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
}
}
}
}
static
void
__Pyx_BufFmt_RaiseExpected
(
__Pyx_BufFmt_Context
*
ctx
)
{
static
void
__Pyx_BufFmt_RaiseExpected
(
__Pyx_BufFmt_Context
*
ctx
)
{
if
(
ctx
->
head
==
NULL
||
ctx
->
head
->
field
==
&
ctx
->
root
)
{
if
(
ctx
->
head
==
NULL
||
ctx
->
head
->
field
==
&
ctx
->
root
)
{
const
char
*
expected
;
const
char
*
expected
;
...
@@ -519,3 +524,60 @@ static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
...
@@ -519,3 +524,60 @@ static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
if
(
info
->
suboffsets
==
__Pyx_minusones
)
info
->
suboffsets
=
NULL
;
if
(
info
->
suboffsets
==
__Pyx_minusones
)
info
->
suboffsets
=
NULL
;
__Pyx_ReleaseBuffer
(
info
);
__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":
...
@@ -12,6 +12,10 @@ cdef extern from "Python.h":
PyBUF_ANY_CONTIGUOUS
PyBUF_ANY_CONTIGUOUS
PyBUF_FORMAT
PyBUF_FORMAT
void
Py_INCREF
(
object
)
void
Py_DECREF
(
object
)
cdef
extern
from
*
:
cdef
extern
from
*
:
object
__pyx_memoryview_new
(
object
obj
,
int
flags
)
object
__pyx_memoryview_new
(
object
obj
,
int
flags
)
...
@@ -52,6 +56,8 @@ cdef class array:
...
@@ -52,6 +56,8 @@ cdef class array:
self
.
strides
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
self
.
strides
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
if
not
self
.
shape
or
not
self
.
strides
:
if
not
self
.
shape
or
not
self
.
strides
:
free
(
self
.
shape
)
free
(
self
.
strides
)
raise
MemoryError
(
"unable to allocate shape or strides."
)
raise
MemoryError
(
"unable to allocate shape or strides."
)
cdef
int
idx
cdef
int
idx
...
@@ -93,7 +99,6 @@ cdef class array:
...
@@ -93,7 +99,6 @@ cdef class array:
raise
MemoryError
(
"unable to allocate array data."
)
raise
MemoryError
(
"unable to allocate array data."
)
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
cdef
int
bufmode
=
-
1
cdef
int
bufmode
=
-
1
if
self
.
mode
==
b"c"
:
if
self
.
mode
==
b"c"
:
bufmode
=
PyBUF_C_CONTIGUOUS
|
PyBUF_ANY_CONTIGUOUS
bufmode
=
PyBUF_C_CONTIGUOUS
|
PyBUF_ANY_CONTIGUOUS
...
@@ -114,27 +119,28 @@ cdef class array:
...
@@ -114,27 +119,28 @@ cdef class array:
else
:
else
:
info
.
format
=
NULL
info
.
format
=
NULL
#
we do not need to call releasebuffer
#
info.obj = self
info
.
obj
=
None
# Py_INCREF(self)
def
__releasebuffer__
(
array
self
,
Py_buffer
*
info
):
def
__releasebuffer__
(
self
,
Py_buffer
*
info
):
# array.__releasebuffer__ should not be called,
pass
# because the Py_buffer's 'obj' field is set to None.
raise
NotImplementedError
()
def
__dealloc__
(
array
self
):
def
__dealloc__
(
array
self
):
if
self
.
data
:
if
self
.
callback_free_data
!=
NULL
:
if
self
.
callback_free_data
!=
NULL
:
self
.
callback_free_data
(
self
.
data
)
self
.
callback_free_data
(
self
.
data
)
else
:
else
:
free
(
self
.
data
)
free
(
self
.
data
)
self
.
data
=
NULL
self
.
data
=
NULL
if
self
.
strides
:
if
self
.
strides
:
free
(
self
.
strides
)
free
(
self
.
strides
)
self
.
strides
=
NULL
self
.
strides
=
NULL
if
self
.
shape
:
if
self
.
shape
:
free
(
self
.
shape
)
free
(
self
.
shape
)
self
.
shape
=
NULL
self
.
shape
=
NULL
self
.
format
=
NULL
self
.
format
=
NULL
self
.
itemsize
=
0
self
.
itemsize
=
0
...
@@ -148,8 +154,15 @@ cdef class array:
...
@@ -148,8 +154,15 @@ cdef class array:
@
cname
(
"__pyx_array_new"
)
@
cname
(
"__pyx_array_new"
)
cdef
array
array_cwrapper
(
tuple
shape
,
Py_ssize_t
itemsize
,
char
*
format
,
char
*
mode
):
cdef
array
array_cwrapper
(
tuple
shape
,
Py_ssize_t
itemsize
,
char
*
format
,
char
*
mode
,
char
*
buf
):
return
array
(
shape
,
itemsize
,
format
,
mode
.
decode
(
'ASCII'
))
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 ##########
########## View.MemoryView ##########
...
@@ -169,14 +182,7 @@ cdef extern from *:
...
@@ -169,14 +182,7 @@ cdef extern from *:
int
__Pyx_GetBuffer
(
object
,
Py_buffer
*
,
int
)
except
-
1
int
__Pyx_GetBuffer
(
object
,
Py_buffer
*
,
int
)
except
-
1
void
__Pyx_ReleaseBuffer
(
Py_buffer
*
)
void
__Pyx_ReleaseBuffer
(
Py_buffer
*
)
ctypedef
struct
{{
memviewslice_name
}}:
ctypedef
struct
PyObject
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
*
,
...)
@
cname
(
'__pyx_MemviewEnum'
)
@
cname
(
'__pyx_MemviewEnum'
)
...
@@ -206,14 +212,18 @@ cdef class memoryview(object):
...
@@ -206,14 +212,18 @@ cdef class memoryview(object):
def
__cinit__
(
memoryview
self
,
object
obj
,
int
flags
):
def
__cinit__
(
memoryview
self
,
object
obj
,
int
flags
):
self
.
obj
=
obj
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
()
self
.
lock
=
PyThread_allocate_lock
()
if
self
.
lock
==
NULL
:
if
self
.
lock
==
NULL
:
raise
MemoryError
raise
MemoryError
def
__dealloc__
(
memoryview
self
):
def
__dealloc__
(
memoryview
self
):
__Pyx_ReleaseBuffer
(
&
self
.
view
)
if
self
.
obj
is
not
None
:
__Pyx_ReleaseBuffer
(
&
self
.
view
)
if
self
.
lock
!=
NULL
:
if
self
.
lock
!=
NULL
:
PyThread_free_lock
(
self
.
lock
)
PyThread_free_lock
(
self
.
lock
)
...
@@ -265,7 +275,11 @@ cdef class memoryview(object):
...
@@ -265,7 +275,11 @@ cdef class memoryview(object):
cdef
bytes
bytesitem
cdef
bytes
bytesitem
# Do a manual and complete check here instead of this easy hack
# Do a manual and complete check here instead of this easy hack
bytesitem
=
itemp
[:
self
.
view
.
itemsize
]
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
):
cdef
assign_item_from_object
(
self
,
char
*
itemp
,
object
value
):
"""Only used if instantiated manually by the user, or if Cython doesn't
"""Only used if instantiated manually by the user, or if Cython doesn't
...
@@ -283,11 +297,92 @@ cdef class memoryview(object):
...
@@ -283,11 +297,92 @@ cdef class memoryview(object):
for
i
,
c
in
enumerate
(
bytesvalue
):
for
i
,
c
in
enumerate
(
bytesvalue
):
itemp
[
i
]
=
c
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
):
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
):
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'
)
@
cname
(
'__pyx_memoryviewslice'
)
...
@@ -296,17 +391,14 @@ cdef class _memoryviewslice(memoryview):
...
@@ -296,17 +391,14 @@ cdef class _memoryviewslice(memoryview):
# We need this to keep our shape/strides/suboffset pointers valid
# We need this to keep our shape/strides/suboffset pointers valid
cdef
{{
memviewslice_name
}}
from_slice
cdef
{{
memviewslice_name
}}
from_slice
#
Restore the original Py_buffer before releasing
#
We need this only to print it's classes name
cdef
Py_buffer
orig_view
cdef
object
from_object
cdef
object
(
*
to_object_func
)(
char
*
)
cdef
object
(
*
to_object_func
)(
char
*
)
cdef
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
cdef
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
def
__cinit__
(
self
,
object
obj
,
int
flags
):
self
.
orig_view
=
self
.
view
def
__dealloc__
(
self
):
def
__dealloc__
(
self
):
self
.
view
=
self
.
orig_view
__PYX_XDEC_MEMVIEW
(
&
self
.
from_slice
,
1
)
cdef
convert_item_to_object
(
self
,
char
*
itemp
):
cdef
convert_item_to_object
(
self
,
char
*
itemp
):
if
self
.
to_object_func
!=
NULL
:
if
self
.
to_object_func
!=
NULL
:
...
@@ -320,21 +412,29 @@ cdef class _memoryviewslice(memoryview):
...
@@ -320,21 +412,29 @@ cdef class _memoryviewslice(memoryview):
else
:
else
:
memoryview
.
assign_item_from_object
(
self
,
itemp
,
value
)
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'
)
@
cname
(
'__pyx_memoryview_fromslice'
)
cdef
memoryview_from_memslice_cwrapper
(
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
*
),
object
(
*
to_object_func
)(
char
*
),
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
):
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
]
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
.
shape
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
shape
+
new_ndim
)
result
.
view
.
strides
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
strides
+
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
)
result
.
view
.
suboffsets
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
suboffsets
+
new_ndim
)
...
@@ -345,51 +445,55 @@ cdef memoryview_from_memslice_cwrapper(
...
@@ -345,51 +445,55 @@ cdef memoryview_from_memslice_cwrapper(
return
result
return
result
cdef
_check_index
(
index
):
############### BufferFormatFromTypeInfo ###############
if
not
PyIndex_Check
(
index
)
:
cdef
extern
from
*
:
raise
TypeError
(
"Cannot index with %s"
%
type
(
index
))
ctypedef
struct
__Pyx_StructField
cdef
tuple
_unellipsify
(
tuple
tup
,
int
ndim
):
ctypedef
struct
__Pyx_TypeInfo
:
if
Ellipsis
in
tup
:
char
*
name
result
=
[]
__Pyx_StructField
*
fields
for
idx
,
item
in
enumerate
(
tup
):
size_t
size
if
item
is
Ellipsis
:
char
typegroup
result
.
extend
([
slice
(
None
)]
*
(
ndim
-
len
(
tup
)
+
1
))
char
is_unsigned
result
.
extend
(
tup
[
idx
+
1
:])
break
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'
)
struct
__pyx_typeinfo_string
:
cdef
char
*
pybuffer_index
(
Py_buffer
*
view
,
char
*
bufp
,
Py_ssize_t
index
,
int
dim
)
except
NULL
:
char
string
[
3
]
cdef
Py_ssize_t
shape
,
stride
,
suboffset
=
-
1
cdef
Py_ssize_t
itemsize
=
view
.
itemsize
cdef
char
*
resultp
if
view
.
ndim
==
0
:
__pyx_typeinfo_string
__Pyx_TypeInfoToFormat
(
__Pyx_TypeInfo
*
)
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
:
@
cname
(
'__pyx_format_from_typeinfo'
)
raise
IndexError
(
"Out of bounds on buffer access (axis %d)"
%
dim
)
cdef
format_from_typeinfo
(
__Pyx_TypeInfo
*
type
):
cdef
__Pyx_StructField
*
field
cdef
__pyx_typeinfo_string
fmt
resultp
=
bufp
+
index
*
stride
if
type
.
typegroup
==
'S'
:
if
suboffset
>=
0
:
assert
type
.
fields
!=
NULL
and
type
.
fields
.
type
!=
NULL
resultp
=
(
<
char
**>
resultp
)[
0
]
+
suboffset
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
...
@@ -56,9 +56,8 @@ static CYTHON_INLINE char *__pyx_memviewslice_index_full(const char *bufp, Py_ss
{{
#
__Pyx_PyObject_to_MemoryviewSlice_
<
count
>
}}
{{
#
__Pyx_PyObject_to_MemoryviewSlice_
<
count
>
}}
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
obj
)
{
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
obj
)
{
{{
memviewslice_name
}}
result
;
{{
memviewslice_name
}}
result
=
{
0
};
result
.
memview
=
NULL
;
result
.
data
=
NULL
;
struct
__pyx_memoryview_obj
*
memview
=
\
struct
__pyx_memoryview_obj
*
memview
=
\
(
struct
__pyx_memoryview_obj
*
)
__pyx_memoryview_new
(
obj
,
{{
buf_flag
}});
(
struct
__pyx_memoryview_obj
*
)
__pyx_memoryview_new
(
obj
,
{{
buf_flag
}});
__Pyx_BufFmt_StackElem
stack
[{{
struct_nesting_depth
}}];
__Pyx_BufFmt_StackElem
stack
[{{
struct_nesting_depth
}}];
...
@@ -294,9 +293,9 @@ static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice,
...
@@ -294,9 +293,9 @@ static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
memview
->
acquisition_count
,
lineno
);
memview
->
acquisition_count
,
lineno
);
//
PyThread_acquire_lock(memview->lock, 1);
PyThread_acquire_lock
(
memview
->
lock
,
1
);
first_time
=
(
memview
->
acquisition_count
++
==
0
);
first_time
=
(
memview
->
acquisition_count
++
==
0
);
//
PyThread_release_lock(memview->lock);
PyThread_release_lock
(
memview
->
lock
);
if
(
first_time
)
{
if
(
first_time
)
{
if
(
have_gil
)
{
if
(
have_gil
)
{
...
@@ -321,9 +320,9 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
...
@@ -321,9 +320,9 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
memview
->
acquisition_count
,
lineno
);
memview
->
acquisition_count
,
lineno
);
//
PyThread_acquire_lock(memview->lock, 1);
PyThread_acquire_lock
(
memview
->
lock
,
1
);
last_time
=
(
memview
->
acquisition_count
--
==
1
);
last_time
=
(
memview
->
acquisition_count
--
==
1
);
//
PyThread_release_lock(memview->lock);
PyThread_release_lock
(
memview
->
lock
);
if
(
last_time
)
{
if
(
last_time
)
{
if
(
have_gil
)
{
if
(
have_gil
)
{
...
@@ -370,7 +369,7 @@ static __Pyx_memviewslice {{copy_name}}(const __Pyx_memviewslice from_mvs) {
...
@@ -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
))
{
if
(
unlikely
(
!
array_obj
))
{
goto
fail
;
goto
fail
;
}
}
...
@@ -412,12 +411,15 @@ no_fail:
...
@@ -412,12 +411,15 @@ no_fail:
/////////////// MemviewSliceIndex ///////////////
/////////////// 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
;
bufp
=
bufp
+
idx
*
stride
;
if
(
suboffset
>=
0
)
{
if
(
suboffset
>=
0
)
{
bufp
=
*
((
char
**
)
bufp
)
+
suboffset
;
bufp
=
*
((
char
**
)
bufp
)
+
suboffset
;
}
}
return
bufp
;
return
(
char
*
)
bufp
;
}
}
/////////////// MemviewDtypeToObject.proto ///////////////
/////////////// MemviewDtypeToObject.proto ///////////////
...
...
tests/run/cythonarray.pyx
View file @
917cce5e
...
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
...
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
from
cython
cimport
array
from
cython
cimport
array
cimport
cython
as
cy
cimport
cython
as
cy
from
libc.stdlib
cimport
malloc
,
free
def
contiguity
():
def
contiguity
():
'''
'''
>>> contiguity()
>>> contiguity()
...
@@ -85,19 +87,79 @@ cdef create_array(shape, mode):
...
@@ -85,19 +87,79 @@ cdef create_array(shape, mode):
return
result
return
result
def
test_cython_array
():
def
test_cython_array
_getbuffer
():
"""
"""
>>> test_cython_array()
>>> test_cython_array
_getbuffer
()
98
98
61
61
98
98
61
61
"""
"""
cdef
int
[:,
::
1
]
carr
=
create_array
((
14
,
10
),
'c'
)
cdef
int
[:,
::
1
]
cslice
=
create_array
((
14
,
10
),
'c'
)
cdef
int
[::
1
,
:]
farr
=
create_array
((
14
,
10
),
'fortran'
)
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
(
<
int
[:
10
:
1
,
:
10
]
>
getp
()).
mode
print
carr
[
6
,
1
]
print
farr
[
9
,
8
]
cdef
int
[:,
::
1
]
mslice
=
<
int
[:
10
,
:
10
]
>
getp
()
print
farr
[
6
,
1
]
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):
...
@@ -219,28 +219,20 @@ def get_int_2d(int[:, :] mslice, int i, int j):
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> get_int_2d(C, 1, 1)
>>> get_int_2d(C, 1, 1)
acquired C
acquired C
acquired C
released C
released C
released C
4
4
Check negative indexing:
Check negative indexing:
>>> get_int_2d(C, -1, 0)
>>> get_int_2d(C, -1, 0)
acquired C
acquired C
acquired C
released C
released C
released C
3
3
>>> get_int_2d(C, -1, -2)
>>> get_int_2d(C, -1, -2)
acquired C
acquired C
acquired C
released C
released C
released C
4
4
>>> get_int_2d(C, -2, -3)
>>> get_int_2d(C, -2, -3)
acquired C
acquired C
acquired C
released C
released C
released C
0
0
...
@@ -265,50 +257,34 @@ def set_int_2d(int[:, :] mslice, int i, int j, int value):
...
@@ -265,50 +257,34 @@ def set_int_2d(int[:, :] mslice, int i, int j, int value):
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> C = IntMockBuffer("C", range(6), (2,3))
>>> set_int_2d(C, 1, 1, 10)
>>> set_int_2d(C, 1, 1, 10)
acquired C
acquired C
acquired C
released C
released C
released C
>>> get_int_2d(C, 1, 1)
>>> get_int_2d(C, 1, 1)
acquired C
acquired C
acquired C
released C
released C
released C
10
10
Check negative indexing:
Check negative indexing:
>>> set_int_2d(C, -1, 0, 3)
>>> set_int_2d(C, -1, 0, 3)
acquired C
acquired C
acquired C
released C
released C
released C
>>> get_int_2d(C, -1, 0)
>>> get_int_2d(C, -1, 0)
acquired C
acquired C
acquired C
released C
released C
released C
3
3
>>> set_int_2d(C, -1, -2, 8)
>>> set_int_2d(C, -1, -2, 8)
acquired C
acquired C
acquired C
released C
released C
released C
>>> get_int_2d(C, -1, -2)
>>> get_int_2d(C, -1, -2)
acquired C
acquired C
acquired C
released C
released C
released C
8
8
>>> set_int_2d(C, -2, -3, 9)
>>> set_int_2d(C, -2, -3, 9)
acquired C
acquired C
acquired C
released C
released C
released C
>>> get_int_2d(C, -2, -3)
>>> get_int_2d(C, -2, -3)
acquired C
acquired C
acquired C
released C
released C
released C
9
9
...
@@ -336,8 +312,6 @@ def writable(unsigned short int[:, :, :] mslice):
...
@@ -336,8 +312,6 @@ def writable(unsigned short int[:, :, :] mslice):
>>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3))
>>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3))
>>> writable(R)
>>> writable(R)
acquired R
acquired R
acquired R
released R
released R
released R
>>> [str(x) for x in R.recieved_flags] # Py2/3
>>> [str(x) for x in R.recieved_flags] # Py2/3
['FORMAT', 'ND', 'STRIDES', 'WRITABLE']
['FORMAT', 'ND', 'STRIDES', 'WRITABLE']
...
@@ -350,8 +324,6 @@ def strided(int[:] mslice):
...
@@ -350,8 +324,6 @@ def strided(int[:] mslice):
>>> A = IntMockBuffer("A", range(4))
>>> A = IntMockBuffer("A", range(4))
>>> strided(A)
>>> strided(A)
acquired A
acquired A
acquired A
released A
released A
released A
2
2
...
@@ -410,16 +382,12 @@ def generic(int[::view.generic, ::view.generic] mslice1,
...
@@ -410,16 +382,12 @@ def generic(int[::view.generic, ::view.generic] mslice1,
>>> generic(A, B)
>>> generic(A, B)
acquired A
acquired A
acquired B
acquired B
acquired A
acquired B
4
4
4
4
10
10
11
11
released A
released A
released B
released B
released A
released B
"""
"""
buf1
,
buf2
=
mslice1
,
mslice2
buf1
,
buf2
=
mslice1
,
mslice2
...
@@ -440,16 +408,12 @@ def generic_contig(int[::view.generic_contiguous, :] mslice1,
...
@@ -440,16 +408,12 @@ def generic_contig(int[::view.generic_contiguous, :] mslice1,
>>> generic_contig(A, B)
>>> generic_contig(A, B)
acquired A
acquired A
acquired B
acquired B
acquired A
acquired B
4
4
4
4
10
10
11
11
released A
released A
released B
released B
released A
released B
"""
"""
buf1
,
buf2
=
mslice1
,
mslice2
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