Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
e31c8f6f
Commit
e31c8f6f
authored
Aug 20, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support transposing memoryview objects and slices
parent
2e17dee8
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
21 deletions
+82
-21
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+29
-5
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+0
-1
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+30
-15
tests/run/numpy_memoryview.pyx
tests/run/numpy_memoryview.pyx
+23
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
e31c8f6f
...
...
@@ -2892,7 +2892,7 @@ class IndexNode(ExprNode):
buffer_entry
=
self
.
buffer_entry
()
if
buffer_entry
.
type
.
is_buffer
:
negative_indices
=
entry
.
type
.
negative_indices
negative_indices
=
buffer_
entry
.
type
.
negative_indices
else
:
negative_indices
=
Buffer
.
buffer_defaults
[
'negative_indices'
]
...
...
@@ -3861,6 +3861,7 @@ class AttributeNode(ExprNode):
entry
=
None
is_called
=
0
needs_none_check
=
True
is_memslice_transpose
=
False
def
as_cython_attribute
(
self
):
if
(
isinstance
(
self
.
obj
,
NameNode
)
and
...
...
@@ -4061,6 +4062,13 @@ class AttributeNode(ExprNode):
if
obj_type
.
attributes_known
():
if
(
obj_type
.
is_memoryviewslice
and
not
obj_type
.
scope
.
lookup_here
(
self
.
attribute
)):
if
self
.
attribute
==
'T'
:
self
.
is_memslice_transpose
=
True
self
.
is_temp
=
True
self
.
use_managed_ref
=
True
self
.
type
=
self
.
obj
.
type
return
else
:
obj_type
.
declare_attribute
(
self
.
attribute
)
entry
=
obj_type
.
scope
.
lookup_here
(
self
.
attribute
)
if
entry
and
entry
.
is_member
:
...
...
@@ -4169,15 +4177,31 @@ class AttributeNode(ExprNode):
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
elif
self
.
type
.
is_memoryviewslice
:
if
self
.
initialized_check
:
if
self
.
is_memslice_transpose
:
# transpose the slice
if
self
.
in_nogil_context
:
error
(
self
.
pos
,
"Cannot transpose slice in nogil mode"
)
return
for
access
,
packing
in
self
.
type
.
axes
:
if
access
==
'ptr'
:
error
(
self
.
pos
,
"Transposing not supported for slices "
"with indirect dimensions"
)
return
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
obj
.
result
()))
if
self
.
obj
.
is_name
:
code
.
put_incref_memoryviewslice
(
self
.
result
(),
have_gil
=
True
)
T
=
"__pyx_memslice_transpose(&%s) == 0"
code
.
putln
(
code
.
error_goto_if
(
T
%
self
.
result
(),
self
.
pos
))
elif
self
.
initialized_check
:
code
.
putln
(
'if (unlikely(!%s.memview)) {'
'PyErr_SetString(PyExc_AttributeError,'
'"Memoryview is not initialized");'
'%s'
'}'
%
(
self
.
result
(),
code
.
error_goto
(
self
.
pos
)))
#code.putln("%s = %s;" % (self.result(),
# self.calculate_result_code()))
else
:
# result_code contains what is needed, but we may need to insert
# a check and raise an exception
...
...
Cython/Compiler/PyrexTypes.py
View file @
e31c8f6f
...
...
@@ -510,7 +510,6 @@ class MemoryViewSliceType(PyrexType):
entry
.
utility_code_definition
=
\
MemoryView
.
IsContigFuncUtilCode
(
c_or_f
)
return
True
def
specialization_suffix
(
self
):
...
...
Cython/Utility/MemoryView.pyx
View file @
e31c8f6f
...
...
@@ -306,17 +306,8 @@ cdef class memoryview(object):
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
]
cdef
_memoryviewslice
result
=
memoryview_copy
(
self
)
transpose_memslice
(
&
result
.
from_slice
)
return
result
property
_obj
:
...
...
@@ -409,7 +400,7 @@ cdef memoryview memview_slice(memoryview memview, object indices):
memviewsliceobj
=
memview
p_src
=
&
memviewsliceobj
.
from_slice
else
:
create_slice
(
memview
,
&
src
)
slice_copy
(
memview
,
&
src
)
p_src
=
&
src
# Note: don't use variable src at this point
...
...
@@ -623,6 +614,30 @@ cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
return
resultp
#
### Transposing a memoryviewslice
#
@
cname
(
'__pyx_memslice_transpose'
)
cdef
int
transpose_memslice
({{
memviewslice_name
}}
*
memslice
)
except
0
:
cdef
int
ndim
=
memslice
.
memview
.
view
.
ndim
cdef
Py_ssize_t
*
shape
=
memslice
.
shape
cdef
Py_ssize_t
*
strides
=
memslice
.
strides
# reverse strides and shape
cdef
int
i
,
j
for
i
in
range
(
ndim
/
2
):
j
=
ndim
-
1
-
i
strides
[
i
],
strides
[
j
]
=
strides
[
j
],
strides
[
i
]
shape
[
i
],
shape
[
j
]
=
shape
[
j
],
shape
[
i
]
if
memslice
.
suboffsets
[
i
]
>=
0
or
memslice
.
suboffsets
[
j
]
>=
0
:
dim
=
i
if
memslice
.
suboffsets
[
i
]
>=
0
else
j
raise
ValueError
(
"Cannot transpose view with indirect dimension "
"(axis %d)"
%
dim
)
return
1
#
### Creating new memoryview objects from slices and memoryviews
#
...
...
@@ -694,8 +709,8 @@ cdef memoryview_fromslice({{memviewslice_name}} *memviewslice,
return
result
@
cname
(
'__pyx_memoryview_
create_slice
'
)
cdef
void
create_slice
(
memoryview
memview
,
{{
memviewslice_name
}}
*
dst
):
@
cname
(
'__pyx_memoryview_
slice_copy
'
)
cdef
void
slice_copy
(
memoryview
memview
,
{{
memviewslice_name
}}
*
dst
):
cdef
int
dim
dst
.
memview
=
<
__pyx_memoryview
*>
memview
...
...
@@ -712,7 +727,7 @@ cdef memoryview_copy(memoryview memview):
cdef
object
(
*
to_object_func
)(
char
*
)
cdef
int
(
*
to_dtype_func
)(
char
*
,
object
)
except
0
create_slice
(
memview
,
&
memviewslice
)
slice_copy
(
memview
,
&
memviewslice
)
if
isinstance
(
memview
,
_memoryviewslice
):
to_object_func
=
(
<
_memoryviewslice
>
memview
).
to_object_func
...
...
tests/run/numpy_memoryview.pyx
View file @
e31c8f6f
...
...
@@ -140,3 +140,26 @@ def test_ellipsis_memoryview(array):
e_obj
=
array
[...,
5
,
6
]
ae
(
e
.
shape
[
0
],
e_obj
.
shape
[
0
])
ae
(
e
.
strides
[
0
],
e_obj
.
strides
[
0
])
def
test_transpose
():
"""
>>> test_transpose()
3 4
(3, 4)
(3, 4)
11 11 11 11 11 11
"""
cdef
dtype_t
[:,
:]
a
numpy_obj
=
np
.
arange
(
4
*
3
,
dtype
=
np
.
int32
).
reshape
(
4
,
3
)
a
=
numpy_obj
a_obj
=
a
cdef
dtype_t
[:,
:]
b
=
a
.
T
print
a
.
T
.
shape
[
0
],
a
.
T
.
shape
[
1
]
print
a_obj
.
T
.
shape
print
numpy_obj
.
T
.
shape
print
a
[
3
,
2
],
a
.
T
[
2
,
3
],
a_obj
[
3
,
2
],
a_obj
.
T
[
2
,
3
],
numpy_obj
[
3
,
2
],
numpy_obj
.
T
[
2
,
3
]
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