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
8105941c
Commit
8105941c
authored
Aug 15, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support slicing memoryview objects
parent
155a4ef5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
469 additions
and
96 deletions
+469
-96
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+4
-8
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+4
-1
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+16
-9
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+1
-3
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+218
-68
tests/run/memoryview.pyx
tests/run/memoryview.pyx
+73
-0
tests/run/memoryviewattrs.pyx
tests/run/memoryviewattrs.pyx
+13
-7
tests/run/numpy_memoryview.pyx
tests/run/numpy_memoryview.pyx
+140
-0
No files found.
Cython/Compiler/CythonScope.py
View file @
8105941c
...
@@ -83,20 +83,16 @@ class CythonScope(ModuleScope):
...
@@ -83,20 +83,16 @@ class CythonScope(ModuleScope):
#
#
# The view sub-scope
# The view sub-scope
#
#
self
.
viewscope
=
viewscope
=
ModuleScope
(
u'cython.view'
,
self
,
None
)
self
.
viewscope
=
viewscope
=
ModuleScope
(
u'view'
,
self
,
None
)
self
.
declare_module
(
'view'
,
viewscope
,
None
).
as_module
=
viewscope
# Hacky monkey patch
self
.
viewscope
.
global_scope
=
self
.
global_scope
self
.
declare_module
(
'view'
,
viewscope
,
None
)
viewscope
.
is_cython_builtin
=
True
viewscope
.
is_cython_builtin
=
True
viewscope
.
pxd_file_loaded
=
True
viewscope
.
pxd_file_loaded
=
True
cythonview_testscope_utility_code
.
declare_in_scope
(
viewscope
)
cythonview_testscope_utility_code
.
declare_in_scope
(
viewscope
)
view_utility_scope
=
MemoryView
.
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.from_scope = view_utility_scope
MemoryView
.
memview_fromslice_utility_code
.
declare_in_scope
(
viewscope
)
#
MemoryView.memview_fromslice_utility_code.declare_in_scope(viewscope)
def
create_cython_scope
(
context
,
create_testscope
):
def
create_cython_scope
(
context
,
create_testscope
):
...
...
Cython/Compiler/ExprNodes.py
View file @
8105941c
...
@@ -2452,7 +2452,10 @@ class IndexNode(ExprNode):
...
@@ -2452,7 +2452,10 @@ class IndexNode(ExprNode):
if
isinstance
(
index
,
SliceNode
):
if
isinstance
(
index
,
SliceNode
):
suboffsets_dim
=
i
suboffsets_dim
=
i
self
.
memslice_slice
=
True
self
.
memslice_slice
=
True
axes
.
append
((
access
,
'strided'
))
if
packing
==
'contig'
and
index
.
step
.
is_none
:
axes
.
append
((
access
,
'contig'
))
else
:
axes
.
append
((
access
,
'strided'
))
# Coerce start, stop and step to temps of the right type
# Coerce start, stop and step to temps of the right type
for
attr
in
(
'start'
,
'stop'
,
'step'
):
for
attr
in
(
'start'
,
'stop'
,
'step'
):
...
...
Cython/Compiler/MemoryView.py
View file @
8105941c
...
@@ -412,15 +412,18 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
...
@@ -412,15 +412,18 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
for
temp
in
temps
:
for
temp
in
temps
:
code
.
funcstate
.
release_temp
(
temp
)
code
.
funcstate
.
release_temp
(
temp
)
def
empty_slice
(
pos
):
none
=
ExprNodes
.
NoneNode
(
pos
)
return
ExprNodes
.
SliceNode
(
pos
,
start
=
none
,
stop
=
none
,
step
=
none
)
def
unellipsify
(
indices
,
ndim
):
def
unellipsify
(
indices
,
ndim
):
result
=
[]
result
=
[]
seen_ellipsis
=
False
seen_ellipsis
=
False
for
index
in
indices
:
for
index
in
indices
:
if
isinstance
(
index
,
ExprNodes
.
EllipsisNode
):
if
isinstance
(
index
,
ExprNodes
.
EllipsisNode
):
none
=
ExprNodes
.
NoneNode
(
index
.
pos
)
full_slice
=
empty_slice
(
index
.
pos
)
full_slice
=
ExprNodes
.
SliceNode
(
index
.
pos
,
start
=
none
,
stop
=
none
,
step
=
none
)
if
seen_ellipsis
:
if
seen_ellipsis
:
result
.
append
(
full_slice
)
result
.
append
(
full_slice
)
else
:
else
:
...
@@ -430,6 +433,10 @@ def unellipsify(indices, ndim):
...
@@ -430,6 +433,10 @@ def unellipsify(indices, ndim):
else
:
else
:
result
.
append
(
index
)
result
.
append
(
index
)
if
len
(
result
)
<
ndim
:
nslices
=
ndim
-
len
(
result
)
result
.
extend
([
empty_slice
(
indices
[
-
1
].
pos
)]
*
nslices
)
return
result
return
result
def
get_memoryview_flag
(
access
,
packing
):
def
get_memoryview_flag
(
access
,
packing
):
...
@@ -950,7 +957,7 @@ def _resolve_AttributeNode(env, node):
...
@@ -950,7 +957,7 @@ def _resolve_AttributeNode(env, node):
scope
=
env
scope
=
env
for
modname
in
modnames
:
for
modname
in
modnames
:
mod
=
scope
.
lookup
(
modname
)
mod
=
scope
.
lookup
(
modname
)
if
not
mod
:
if
not
mod
or
not
mod
.
as_module
:
raise
CompileError
(
raise
CompileError
(
node
.
pos
,
"undeclared name not builtin: %s"
%
modname
)
node
.
pos
,
"undeclared name not builtin: %s"
%
modname
)
scope
=
mod
.
as_module
scope
=
mod
.
as_module
...
@@ -1001,8 +1008,8 @@ cython_array_utility_code = load_memview_cy_utility(
...
@@ -1001,8 +1008,8 @@ cython_array_utility_code = load_memview_cy_utility(
context
=
context
,
context
=
context
,
requires
=
[
view_utility_code
])
requires
=
[
view_utility_code
])
memview_fromslice_utility_code
=
load_memview_cy_utility
(
# memview_fromslice_utility_code = load_memview_cy_utility(
"MemviewFromSlice"
,
# "MemviewFromSlice",
context
=
context
,
# context=context,
requires
=
[
view_utility_code
],
# requires=[view_utility_code],
)
# )
\ No newline at end of file
\ No newline at end of file
Cython/Compiler/PyrexTypes.py
View file @
8105941c
...
@@ -488,6 +488,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -488,6 +488,7 @@ class MemoryViewSliceType(PyrexType):
entry
.
utility_code_definition
=
\
entry
.
utility_code_definition
=
\
MemoryView
.
CopyFuncUtilCode
(
self
,
to_memview
)
MemoryView
.
CopyFuncUtilCode
(
self
,
to_memview
)
elif
attribute
in
(
"is_c_contig"
,
"is_f_contig"
):
# is_c_contig and is_f_contig functions
# is_c_contig and is_f_contig functions
for
(
c_or_f
,
cython_name
)
in
((
'c'
,
'is_c_contig'
),
(
'fortran'
,
'is_f_contig'
)):
for
(
c_or_f
,
cython_name
)
in
((
'c'
,
'is_c_contig'
),
(
'fortran'
,
'is_f_contig'
)):
...
@@ -564,9 +565,6 @@ class MemoryViewSliceType(PyrexType):
...
@@ -564,9 +565,6 @@ 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
...
...
Cython/Utility/MemoryView.pyx
View file @
8105941c
...
@@ -120,7 +120,6 @@ cdef class array:
...
@@ -120,7 +120,6 @@ cdef class array:
info
.
format
=
NULL
info
.
format
=
NULL
# info.obj = self
# info.obj = self
# Py_INCREF(self)
def
__releasebuffer__
(
self
,
Py_buffer
*
info
):
def
__releasebuffer__
(
self
,
Py_buffer
*
info
):
pass
pass
...
@@ -184,6 +183,20 @@ cdef extern from *:
...
@@ -184,6 +183,20 @@ cdef extern from *:
ctypedef
struct
PyObject
ctypedef
struct
PyObject
cdef
struct
__pyx_memoryview
"__pyx_memoryview_obj"
:
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_MemviewEnum'
)
@
cname
(
'__pyx_MemviewEnum'
)
cdef
class
Enum
(
object
):
cdef
class
Enum
(
object
):
...
@@ -229,42 +242,34 @@ cdef class memoryview(object):
...
@@ -229,42 +242,34 @@ cdef class memoryview(object):
cdef
char
*
get_item_pointer
(
memoryview
self
,
object
index
)
except
NULL
:
cdef
char
*
get_item_pointer
(
memoryview
self
,
object
index
)
except
NULL
:
cdef
Py_ssize_t
dim
cdef
Py_ssize_t
dim
cdef
Py_buffer
view
=
self
.
view
cdef
char
*
itemp
=
<
char
*>
self
.
view
.
buf
cdef
char
*
itemp
=
<
char
*>
view
.
buf
if
index
is
Ellipsis
:
for
dim
,
idx
in
enumerate
(
index
):
return
self
_check_index
(
idx
)
itemp
=
pybuffer_index
(
&
self
.
view
,
itemp
,
idx
,
dim
)
elif
isinstance
(
index
,
slice
):
if
index
==
slice
(
None
):
return
self
raise
NotImplementedError
else
:
if
not
isinstance
(
index
,
tuple
):
index
=
(
index
,)
tup
=
_unellipsify
(
index
,
self
.
view
.
ndim
)
if
len
(
tup
)
!=
self
.
view
.
ndim
:
raise
NotImplementedError
(
"Expected %d indices (got %d)"
%
(
self
.
view
.
ndim
,
len
(
tup
)))
for
dim
,
idx
in
enumerate
(
tup
):
_check_index
(
idx
)
itemp
=
pybuffer_index
(
&
self
.
view
,
itemp
,
idx
,
dim
)
return
itemp
return
itemp
@
cname
(
'__pyx_memoryview_getitem'
)
@
cname
(
'__pyx_memoryview_getitem'
)
def
__getitem__
(
memoryview
self
,
object
index
):
def
__getitem__
(
memoryview
self
,
object
index
):
cdef
char
*
itemp
=
self
.
get_item_pointer
(
index
)
if
index
is
Ellipsis
:
return
self
.
convert_item_to_object
(
itemp
)
return
self
have_slices
,
index
=
_unellipsify
(
index
,
self
.
view
.
ndim
)
cdef
char
*
itemp
if
have_slices
:
return
pybuffer_slice
(
self
,
index
)
else
:
itemp
=
self
.
get_item_pointer
(
index
)
return
self
.
convert_item_to_object
(
itemp
)
@
cname
(
'__pyx_memoryview_setitem'
)
@
cname
(
'__pyx_memoryview_setitem'
)
def
__setitem__
(
memoryview
self
,
object
index
,
object
value
):
def
__setitem__
(
memoryview
self
,
object
index
,
object
value
):
have_slices
,
index
=
_unellipsify
(
index
,
self
.
view
.
ndim
)
if
have_slices
:
raise
NotImplementedError
(
"Slice assignment not supported yet"
)
cdef
char
*
itemp
=
self
.
get_item_pointer
(
index
)
cdef
char
*
itemp
=
self
.
get_item_pointer
(
index
)
self
.
assign_item_from_object
(
itemp
,
value
)
self
.
assign_item_from_object
(
itemp
,
value
)
...
@@ -297,6 +302,22 @@ cdef class memoryview(object):
...
@@ -297,6 +302,22 @@ cdef class memoryview(object):
for
i
,
c
in
enumerate
(
bytesvalue
):
for
i
,
c
in
enumerate
(
bytesvalue
):
itemp
[
i
]
=
c
itemp
[
i
]
=
c
property
T
:
@
cname
(
'__pyx_memoryview_transpose'
)
def
__get__
(
self
):
cdef
memoryview
result
=
memoryview_copy
(
self
)
cdef
int
ndim
=
self
.
view
.
ndim
cdef
Py_ssize_t
*
strides
=
result
.
view
.
strides
cdef
Py_ssize_t
*
shape
=
result
.
view
.
shape
# reverse strides and shape
for
i
in
range
(
ndim
/
2
):
strides
[
i
],
strides
[
ndim
-
i
]
=
strides
[
ndim
-
i
],
strides
[
i
]
shape
[
i
],
shape
[
ndim
-
i
]
=
shape
[
ndim
-
i
],
shape
[
i
]
return
result
property
_obj
:
property
_obj
:
@
cname
(
'__pyx_memoryview__get__obj'
)
@
cname
(
'__pyx_memoryview__get__obj'
)
def
__get__
(
self
):
def
__get__
(
self
):
...
@@ -306,6 +327,23 @@ cdef class memoryview(object):
...
@@ -306,6 +327,23 @@ cdef class memoryview(object):
return
self
.
obj
return
self
.
obj
property
shape
:
@
cname
(
'__pyx_memoryview_get_shape'
)
def
__get__
(
self
):
return
tuple
([
self
.
view
.
shape
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
property
strides
:
@
cname
(
'__pyx_memoryview_get_strides'
)
def
__get__
(
self
):
return
tuple
([
self
.
view
.
strides
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
property
suboffsets
:
@
cname
(
'__pyx_memoryview_get_suboffsets'
)
def
__get__
(
self
):
return
tuple
([
self
.
view
.
suboffsets
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
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
))
...
@@ -322,23 +360,130 @@ cdef _check_index(index):
...
@@ -322,23 +360,130 @@ cdef _check_index(index):
if
not
PyIndex_Check
(
index
):
if
not
PyIndex_Check
(
index
):
raise
TypeError
(
"Cannot index with %s"
%
type
(
index
))
raise
TypeError
(
"Cannot index with %s"
%
type
(
index
))
cdef
tuple
_unellipsify
(
tuple
tup
,
int
ndim
):
cdef
tuple
_unellipsify
(
object
index
,
int
ndim
):
if
Ellipsis
in
tup
:
if
not
isinstance
(
index
,
tuple
):
result
=
[]
tup
=
(
index
,)
for
idx
,
item
in
enumerate
(
tup
):
else
:
if
item
is
Ellipsis
:
tup
=
index
result
=
[]
have_slices
=
False
seen_ellipsis
=
False
for
idx
,
item
in
enumerate
(
tup
):
if
item
is
Ellipsis
:
if
not
seen_ellipsis
:
result
.
extend
([
slice
(
None
)]
*
(
ndim
-
len
(
tup
)
+
1
))
result
.
extend
([
slice
(
None
)]
*
(
ndim
-
len
(
tup
)
+
1
))
result
.
extend
(
tup
[
idx
+
1
:])
result
.
extend
(
tup
[
idx
+
1
:])
break
else
:
result
.
append
(
slice
(
None
))
have_slices
=
True
else
:
have_slices
=
have_slices
or
isinstance
(
item
,
slice
)
result
.
append
(
item
)
result
.
append
(
item
)
return
tuple
(
result
)
nslices
=
ndim
-
len
(
result
)
if
nslices
:
return
tup
result
.
extend
([
slice
(
None
)]
*
nslices
)
for
idx
in
tup
:
if
isinstance
(
idx
,
slice
):
return
True
,
tup
return
False
,
tup
@
cname
(
'__pyx_pybuffer_slice'
)
cdef
memoryview
pybuffer_slice
(
memoryview
memview
,
object
indices
):
cdef
Py_ssize_t
idx
,
dim
,
new_dim
=
0
,
suboffset_dim
=
-
1
cdef
Py_ssize_t
shape
,
stride
cdef
bint
negative_step
cdef
int
new_ndim
=
0
cdef
{{
memviewslice_name
}}
dst
for
dim
,
index
in
enumerate
(
indices
):
shape
=
memview
.
view
.
shape
[
dim
]
stride
=
memview
.
view
.
strides
[
dim
]
if
PyIndex_Check
(
index
):
idx
=
index
if
idx
<
0
:
idx
+=
shape
if
not
0
<=
idx
<
shape
:
raise
IndexError
(
"Index out of bounds (axis %d)"
%
dim
)
else
:
# index is a slice
new_ndim
+=
1
start
,
stop
,
step
=
index
.
start
,
index
.
stop
,
index
.
step
negative_step
=
step
and
step
<
0
# set some defaults
if
not
start
:
if
negative_step
:
start
=
shape
-
1
else
:
start
=
0
if
not
stop
:
if
negative_step
:
stop
=
-
1
else
:
stop
=
shape
# check our bounds
if
start
<
0
:
start
+=
shape
if
start
<
0
:
start
=
0
elif
start
>=
shape
:
start
=
shape
-
1
if
stop
<
0
:
stop
+=
shape
if
stop
<
0
:
stop
=
0
elif
stop
>
shape
:
stop
=
shape
step
=
step
or
1
# shape/strides/suboffsets
dst
.
strides
[
new_dim
]
=
stride
*
step
dst
.
shape
[
new_dim
]
=
(
stop
-
start
)
/
step
if
(
stop
-
start
)
%
step
:
dst
.
shape
[
new_dim
]
+=
1
dst
.
suboffsets
[
new_dim
]
=
memview
.
view
.
suboffsets
[
dim
]
# set this for the slicing offset
if
negative_step
:
idx
=
stop
else
:
idx
=
start
# Add the slicing or idexing offsets to the right suboffset or base data *
if
suboffset_dim
<
0
:
dst
.
data
+=
idx
*
stride
else
:
dst
.
suboffsets
[
suboffset_dim
]
+=
idx
*
stride
if
memview
.
view
.
suboffsets
[
dim
]:
if
PyIndex_Check
(
index
):
raise
IndexError
(
"Cannot make indirect dimension %d disappear through "
"indexing, consider slicing with %d:%d"
%
(
dim
,
idx
,
idx
+
1
))
suboffset_dim
=
new_dim
cdef
_memoryviewslice
memviewsliceobj
if
isinstance
(
memview
,
_memoryviewslice
):
memviewsliceobj
=
memview
return
memoryview_fromslice
(
&
dst
,
new_dim
,
memviewsliceobj
.
to_object_func
,
memviewsliceobj
.
to_dtype_func
)
else
:
return
memoryview_fromslice
(
&
dst
,
new_dim
,
NULL
,
NULL
)
@
cname
(
'__pyx_pybuffer_index'
)
@
cname
(
'__pyx_pybuffer_index'
)
cdef
char
*
pybuffer_index
(
Py_buffer
*
view
,
char
*
bufp
,
Py_ssize_t
index
,
int
dim
)
except
NULL
:
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
shape
,
stride
,
suboffset
=
-
1
cdef
Py_ssize_t
itemsize
=
view
.
itemsize
cdef
Py_ssize_t
itemsize
=
view
.
itemsize
cdef
char
*
resultp
cdef
char
*
resultp
...
@@ -366,25 +511,6 @@ cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, int dim
...
@@ -366,25 +511,6 @@ cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, int dim
return
resultp
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'
)
cdef
class
_memoryviewslice
(
memoryview
):
cdef
class
_memoryviewslice
(
memoryview
):
"Internal class for passing memory view slices to Python"
"Internal class for passing memory view slices to Python"
...
@@ -419,15 +545,14 @@ cdef class _memoryviewslice(memoryview):
...
@@ -419,15 +545,14 @@ cdef class _memoryviewslice(memoryview):
@
cname
(
'__pyx_memoryview_fromslice'
)
@
cname
(
'__pyx_memoryview_fromslice'
)
cdef
memoryview_from
_memslice_cwrapper
(
cdef
memoryview_from
slice
({{
memviewslice_name
}}
*
memviewslice
,
{{
memviewslice_name
}}
*
memviewslice
,
int
cur_
ndim
,
int
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
):
assert
0
<
cur_ndim
<=
memviewslice
.
memview
.
view
.
ndim
assert
0
<
ndim
<=
memviewslice
.
memview
.
view
.
ndim
,
(
ndim
,
memviewslice
.
memview
.
view
.
ndim
)
cdef
_memoryviewslice
result
=
_memoryviewslice
(
None
,
0
)
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
)
__PYX_INC_MEMVIEW
(
memviewslice
,
1
)
...
@@ -435,16 +560,41 @@ cdef memoryview_from_memslice_cwrapper(
...
@@ -435,16 +560,41 @@ cdef memoryview_from_memslice_cwrapper(
result
.
from_object
=
<
object
>
memviewslice
.
memview
.
obj
result
.
from_object
=
<
object
>
memviewslice
.
memview
.
obj
result
.
view
=
memviewslice
.
memview
.
view
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
result
.
view
.
strides
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
strides
+
new_ndim
)
result
.
view
.
strides
=
<
Py_ssize_t
*>
result
.
from_slice
.
strides
result
.
view
.
suboffsets
=
<
Py_ssize_t
*>
(
&
result
.
from_slice
.
suboffsets
+
new_ndim
)
result
.
view
.
suboffsets
=
<
Py_ssize_t
*>
&
result
.
from_slice
.
suboffsets
result
.
view
.
ndim
=
cur_
ndim
result
.
view
.
ndim
=
ndim
result
.
to_object_func
=
to_object_func
result
.
to_object_func
=
to_object_func
result
.
to_dtype_func
=
to_dtype_func
result
.
to_dtype_func
=
to_dtype_func
return
result
return
result
cdef
memoryview_copy
(
memoryview
memview
):
cdef
{{
memviewslice_name
}}
memviewslice
cdef
int
dim
cdef
object
(
*
to_object_func
)(
char
*
)
cdef
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
memviewslice
.
memview
=
<
__pyx_memoryview
*>
memview
memviewslice
.
data
=
<
char
*>
memview
.
view
.
buf
# Copy all of these as from_slice will
for
dim
in
range
(
memview
.
view
.
ndim
):
memviewslice
.
shape
[
dim
]
=
memview
.
view
.
shape
[
dim
]
memviewslice
.
strides
[
dim
]
=
memview
.
view
.
strides
[
dim
]
memviewslice
.
suboffsets
[
dim
]
=
memview
.
view
.
suboffsets
[
dim
]
if
isinstance
(
memview
,
_memoryviewslice
):
to_object_func
=
(
<
_memoryviewslice
>
memview
).
to_object_func
to_dtype_func
=
(
<
_memoryviewslice
>
memview
).
to_dtype_func
else
:
to_object_func
=
NULL
to_dtype_func
=
NULL
return
memoryview_fromslice
(
&
memviewslice
,
memview
.
view
.
ndim
,
to_object_func
,
to_dtype_func
)
############### BufferFormatFromTypeInfo ###############
############### BufferFormatFromTypeInfo ###############
cdef
extern
from
*
:
cdef
extern
from
*
:
ctypedef
struct
__Pyx_StructField
ctypedef
struct
__Pyx_StructField
...
...
tests/run/memoryview.pyx
View file @
8105941c
...
@@ -587,3 +587,76 @@ def assign_temporary_to_object(object[:] mslice):
...
@@ -587,3 +587,76 @@ def assign_temporary_to_object(object[:] mslice):
"""
"""
buf
=
mslice
buf
=
mslice
buf
[
1
]
=
{
3
-
2
:
2
+
(
2
*
4
)
-
2
}
buf
[
1
]
=
{
3
-
2
:
2
+
(
2
*
4
)
-
2
}
def
test_slicing
(
arg
):
"""
Test simple slicing
>>> test_slicing(IntMockBuffer("A", range(8 * 14 * 11), shape=(8, 14, 11)))
acquired A
3 9 2
1232 -44 4
-1 -1 -1
released A
Test direct slicing, negative slice oob in dim 2
>>> test_slicing(IntMockBuffer("A", range(1 * 2 * 3), shape=(1, 2, 3)))
acquired A
0 0 2
48 -12 4
-1 -1 -1
released A
Test indirect slicing
>>> L = [[range(k * 12 + j * 4, k * 12 + j * 4 + 4) for j in xrange(3)] for k in xrange(5)]
>>> test_slicing(IntMockBuffer("A", L, shape=(5, 3, 4)))
acquired A
2 0 2
8 -4 4
0 0 -1
released A
"""
cdef
int
[::
view
.
generic
,
::
view
.
generic
,
:]
_a
=
arg
a
=
_a
b
=
a
[
2
:
8
:
2
,
-
4
:
1
:
-
1
,
1
:
3
]
print
b
.
shape
[
0
],
b
.
shape
[
1
],
b
.
shape
[
2
]
print
b
.
strides
[
0
],
b
.
strides
[
1
],
b
.
strides
[
2
]
print
b
.
suboffsets
[
0
],
b
.
suboffsets
[
1
],
b
.
suboffsets
[
2
]
cdef
int
i
,
j
,
k
for
i
in
range
(
b
.
shape
[
0
]):
for
j
in
range
(
b
.
shape
[
1
]):
for
k
in
range
(
b
.
shape
[
2
]):
itemA
=
a
[
2
+
2
*
i
,
-
4
-
j
,
1
+
k
]
itemB
=
b
[
i
,
j
,
k
]
assert
itemA
==
itemB
,
(
i
,
j
,
k
,
itemA
,
itemB
)
def
test_slicing_and_indexing
(
arg
):
"""
>>> a = IntStridedMockBuffer("A", range(10 * 3 * 5), shape=(10, 3, 5))
>>> test_slicing_and_indexing(a)
acquired A
5 2
60 8
126 113
[111]
released A
"""
cdef
int
[:,
:,
:]
_a
=
arg
a
=
_a
b
=
a
[
-
5
:,
1
,
1
::
2
]
c
=
b
[
4
:
1
:
-
1
,
::
-
1
]
d
=
c
[
2
,
1
:
2
]
print
b
.
shape
[
0
],
b
.
shape
[
1
]
print
b
.
strides
[
0
],
b
.
strides
[
1
]
cdef
int
i
,
j
for
i
in
range
(
b
.
shape
[
0
]):
for
j
in
range
(
b
.
shape
[
1
]):
itemA
=
a
[
-
5
+
i
,
1
,
1
+
2
*
j
]
itemB
=
b
[
i
,
j
]
assert
itemA
==
itemB
,
(
i
,
j
,
itemA
,
itemB
)
print
c
[
1
,
1
],
c
[
2
,
0
]
print
[
d
[
i
]
for
i
in
range
(
d
.
shape
[
0
])]
\ No newline at end of file
tests/run/memoryviewattrs.pyx
View file @
8105941c
...
@@ -19,24 +19,30 @@ def test_shape_stride_suboffset():
...
@@ -19,24 +19,30 @@ def test_shape_stride_suboffset():
u'''
u'''
>>> test_shape_stride_suboffset()
>>> test_shape_stride_suboffset()
5 7 11
5 7 11
616 88 8
77 11 1
-1 -1 -1
-1 -1 -1
<BLANKLINE>
5 7 11
5 7 11
8 40 280
1 5 35
-1 -1 -1
-1 -1 -1
<BLANKLINE>
5 7 11
5 7 11
616 88 8
77 11 1
-1 -1 -1
-1 -1 -1
'''
'''
cdef
unsigned
long
[:,:,:]
larr
=
array
((
5
,
7
,
11
),
sizeof
(
unsigned
long
),
'L
'
)
cdef
char
[:,:,:]
larr
=
array
((
5
,
7
,
11
),
1
,
'b
'
)
print
larr
.
shape
[
0
],
larr
.
shape
[
1
],
larr
.
shape
[
2
]
print
larr
.
shape
[
0
],
larr
.
shape
[
1
],
larr
.
shape
[
2
]
print
larr
.
strides
[
0
],
larr
.
strides
[
1
],
larr
.
strides
[
2
]
print
larr
.
strides
[
0
],
larr
.
strides
[
1
],
larr
.
strides
[
2
]
print
larr
.
suboffsets
[
0
],
larr
.
suboffsets
[
1
],
larr
.
suboffsets
[
2
]
print
larr
.
suboffsets
[
0
],
larr
.
suboffsets
[
1
],
larr
.
suboffsets
[
2
]
larr
=
array
((
5
,
7
,
11
),
sizeof
(
unsigned
long
),
'L'
,
mode
=
'fortran'
)
print
larr
=
array
((
5
,
7
,
11
),
1
,
'b'
,
mode
=
'fortran'
)
print
larr
.
shape
[
0
],
larr
.
shape
[
1
],
larr
.
shape
[
2
]
print
larr
.
shape
[
0
],
larr
.
shape
[
1
],
larr
.
shape
[
2
]
print
larr
.
strides
[
0
],
larr
.
strides
[
1
],
larr
.
strides
[
2
]
print
larr
.
strides
[
0
],
larr
.
strides
[
1
],
larr
.
strides
[
2
]
print
larr
.
suboffsets
[
0
],
larr
.
suboffsets
[
1
],
larr
.
suboffsets
[
2
]
print
larr
.
suboffsets
[
0
],
larr
.
suboffsets
[
1
],
larr
.
suboffsets
[
2
]
cdef
unsigned
long
[:,:,:]
c_contig
=
larr
.
copy
()
print
cdef
char
[:,:,:]
c_contig
=
larr
.
copy
()
print
c_contig
.
shape
[
0
],
c_contig
.
shape
[
1
],
c_contig
.
shape
[
2
]
print
c_contig
.
shape
[
0
],
c_contig
.
shape
[
1
],
c_contig
.
shape
[
2
]
print
c_contig
.
strides
[
0
],
c_contig
.
strides
[
1
],
c_contig
.
strides
[
2
]
print
c_contig
.
strides
[
0
],
c_contig
.
strides
[
1
],
c_contig
.
strides
[
2
]
print
c_contig
.
suboffsets
[
0
],
c_contig
.
suboffsets
[
1
],
c_contig
.
suboffsets
[
2
]
print
c_contig
.
suboffsets
[
0
],
c_contig
.
suboffsets
[
1
],
c_contig
.
suboffsets
[
2
]
...
@@ -161,7 +167,7 @@ def test_is_contiguous():
...
@@ -161,7 +167,7 @@ def test_is_contiguous():
print
fort_contig
.
is_c_contig
(),
fort_contig
.
is_f_contig
()
print
fort_contig
.
is_c_contig
(),
fort_contig
.
is_f_contig
()
cdef
int
[:,:,:]
strided
=
fort_contig
cdef
int
[:,:,:]
strided
=
fort_contig
print
strided
.
is_c_contig
(),
strided
.
is_f_contig
()
print
strided
.
is_c_contig
(),
strided
.
is_f_contig
()
print
print
fort_contig
=
fort_contig
.
copy_fortran
()
fort_contig
=
fort_contig
.
copy_fortran
()
print
fort_contig
.
is_c_contig
(),
fort_contig
.
is_f_contig
()
print
fort_contig
.
is_c_contig
(),
fort_contig
.
is_f_contig
()
print
strided
.
is_c_contig
(),
strided
.
is_f_contig
()
print
strided
.
is_c_contig
(),
strided
.
is_f_contig
()
...
...
tests/run/numpy_memoryview.pyx
0 → 100644
View file @
8105941c
# tag: numpy
# mode: run
"""
Test slicing for memoryviews and memoryviewslices
"""
cimport
numpy
as
np
import
numpy
def
get_array
():
# We need to type our array to get a __pyx_get_buffer() that typechecks
# for np.ndarray and calls __getbuffer__ in numpy.pxd
cdef
np
.
ndarray
[
int
,
ndim
=
3
]
a
a
=
numpy
.
arange
(
8
*
14
*
11
).
reshape
(
8
,
14
,
11
)
return
a
a
=
get_array
()
def
ae
(
*
args
):
"assert equals"
for
x
in
args
:
if
x
!=
args
[
0
]:
raise
AssertionError
(
args
)
#
### Test slicing memoryview slices
#
def
test_partial_slicing
(
array
):
"""
>>> test_partial_slicing(a)
"""
cdef
int
[:,
:,
:]
a
=
array
obj
=
array
[
4
]
cdef
int
[:,
:]
b
=
a
[
4
,
:]
cdef
int
[:,
:]
c
=
a
[
4
]
ae
(
b
.
shape
[
0
],
c
.
shape
[
0
],
obj
.
shape
[
0
])
ae
(
b
.
shape
[
1
],
c
.
shape
[
1
],
obj
.
shape
[
1
])
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
def
test_ellipsis
(
array
):
"""
>>> test_ellipsis(a)
"""
cdef
int
[:,
:,
:]
a
=
array
cdef
int
[:,
:]
b
=
a
[...,
4
]
b_obj
=
array
[...,
4
]
cdef
int
[:,
:]
c
=
a
[
4
,
...]
c_obj
=
array
[
4
,
...]
cdef
int
[:,
:]
d
=
a
[
2
:
8
,
...,
2
]
d_obj
=
array
[
2
:
8
,
...,
2
]
ae
(
tuple
([
b
.
shape
[
i
]
for
i
in
range
(
2
)]),
b_obj
.
shape
)
ae
(
tuple
([
b
.
strides
[
i
]
for
i
in
range
(
2
)]),
b_obj
.
strides
)
for
i
in
range
(
b
.
shape
[
0
]):
for
j
in
range
(
b
.
shape
[
1
]):
ae
(
b
[
i
,
j
],
b_obj
[
i
,
j
])
ae
(
tuple
([
c
.
shape
[
i
]
for
i
in
range
(
2
)]),
c_obj
.
shape
)
ae
(
tuple
([
c
.
strides
[
i
]
for
i
in
range
(
2
)]),
c_obj
.
strides
)
for
i
in
range
(
c
.
shape
[
0
]):
for
j
in
range
(
c
.
shape
[
1
]):
ae
(
c
[
i
,
j
],
c_obj
[
i
,
j
])
ae
(
tuple
([
d
.
shape
[
i
]
for
i
in
range
(
2
)]),
d_obj
.
shape
)
ae
(
tuple
([
d
.
strides
[
i
]
for
i
in
range
(
2
)]),
d_obj
.
strides
)
for
i
in
range
(
d
.
shape
[
0
]):
for
j
in
range
(
d
.
shape
[
1
]):
ae
(
d
[
i
,
j
],
d_obj
[
i
,
j
])
cdef
int
[:]
e
=
a
[...,
5
,
6
]
e_obj
=
array
[...,
5
,
6
]
ae
(
e
.
shape
[
0
],
e_obj
.
shape
[
0
])
ae
(
e
.
strides
[
0
],
e_obj
.
strides
[
0
])
#
### Test slicing memoryview objects
#
def
test_partial_slicing_memoryview
(
array
):
"""
>>> test_partial_slicing_memoryview(a)
"""
cdef
int
[:,
:,
:]
_a
=
array
a
=
_a
obj
=
array
[
4
]
b
=
a
[
4
,
:]
c
=
a
[
4
]
ae
(
b
.
shape
[
0
],
c
.
shape
[
0
],
obj
.
shape
[
0
])
ae
(
b
.
shape
[
1
],
c
.
shape
[
1
],
obj
.
shape
[
1
])
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
def
test_ellipsis_memoryview
(
array
):
"""
>>> test_ellipsis_memoryview(a)
"""
cdef
int
[:,
:,
:]
_a
=
array
a
=
_a
b
=
a
[...,
4
]
b_obj
=
array
[...,
4
]
c
=
a
[
4
,
...]
c_obj
=
array
[
4
,
...]
d
=
a
[
2
:
8
,
...,
2
]
d_obj
=
array
[
2
:
8
,
...,
2
]
ae
(
tuple
([
b
.
shape
[
i
]
for
i
in
range
(
2
)]),
b_obj
.
shape
)
ae
(
tuple
([
b
.
strides
[
i
]
for
i
in
range
(
2
)]),
b_obj
.
strides
)
for
i
in
range
(
b
.
shape
[
0
]):
for
j
in
range
(
b
.
shape
[
1
]):
ae
(
b
[
i
,
j
],
b_obj
[
i
,
j
])
ae
(
tuple
([
c
.
shape
[
i
]
for
i
in
range
(
2
)]),
c_obj
.
shape
)
ae
(
tuple
([
c
.
strides
[
i
]
for
i
in
range
(
2
)]),
c_obj
.
strides
)
for
i
in
range
(
c
.
shape
[
0
]):
for
j
in
range
(
c
.
shape
[
1
]):
ae
(
c
[
i
,
j
],
c_obj
[
i
,
j
])
ae
(
tuple
([
d
.
shape
[
i
]
for
i
in
range
(
2
)]),
d_obj
.
shape
)
ae
(
tuple
([
d
.
strides
[
i
]
for
i
in
range
(
2
)]),
d_obj
.
strides
)
for
i
in
range
(
d
.
shape
[
0
]):
for
j
in
range
(
d
.
shape
[
1
]):
ae
(
d
[
i
,
j
],
d_obj
[
i
,
j
])
e
=
a
[...,
5
,
6
]
e_obj
=
array
[...,
5
,
6
]
ae
(
e
.
shape
[
0
],
e_obj
.
shape
[
0
])
ae
(
e
.
strides
[
0
],
e_obj
.
strides
[
0
])
\ No newline at end of file
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