Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xavier Thompson
cython
Commits
155a4ef5
Commit
155a4ef5
authored
Aug 09, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support slicing memoryview slices
parent
917cce5e
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
505 additions
and
85 deletions
+505
-85
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+139
-27
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+225
-14
Cython/Compiler/Pipeline.py
Cython/Compiler/Pipeline.py
+5
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+15
-4
Cython/Compiler/UtilityCode.py
Cython/Compiler/UtilityCode.py
+1
-1
Cython/Utility/MemoryView_C.c
Cython/Utility/MemoryView_C.c
+4
-7
tests/run/cythonarray.pyx
tests/run/cythonarray.pyx
+2
-21
tests/run/cythonarrayutil.pxi
tests/run/cythonarrayutil.pxi
+26
-0
tests/run/memslice.pyx
tests/run/memslice.pyx
+88
-9
No files found.
Cython/Compiler/ExprNodes.py
View file @
155a4ef5
This diff is collapsed.
Click to expand it.
Cython/Compiler/MemoryView.py
View file @
155a4ef5
This diff is collapsed.
Click to expand it.
Cython/Compiler/Pipeline.py
View file @
155a4ef5
...
@@ -192,7 +192,6 @@ def create_pipeline(context, mode, exclude_classes=()):
...
@@ -192,7 +192,6 @@ def create_pipeline(context, mode, exclude_classes=()):
FinalOptimizePhase
(
context
),
FinalOptimizePhase
(
context
),
GilCheck
(),
GilCheck
(),
UseUtilityCodeDefinitions
(
context
),
UseUtilityCodeDefinitions
(
context
),
# PrintTree(),
]
]
filtered_stages
=
[]
filtered_stages
=
[]
for
s
in
stages
:
for
s
in
stages
:
...
@@ -293,7 +292,9 @@ def insert_into_pipeline(pipeline, transform, before=None, after=None):
...
@@ -293,7 +292,9 @@ def insert_into_pipeline(pipeline, transform, before=None, after=None):
# Running a pipeline
# Running a pipeline
#
#
def
run_pipeline
(
pipeline
,
source
):
def
run_pipeline
(
pipeline
,
source
,
printtree
=
True
):
from
Cython.Compiler.Visitor
import
PrintTree
error
=
None
error
=
None
data
=
source
data
=
source
try
:
try
:
...
@@ -303,6 +304,8 @@ def run_pipeline(pipeline, source):
...
@@ -303,6 +304,8 @@ def run_pipeline(pipeline, source):
if
DebugFlags
.
debug_verbose_pipeline
:
if
DebugFlags
.
debug_verbose_pipeline
:
t
=
time
()
t
=
time
()
print
"Entering pipeline phase %r"
%
phase
print
"Entering pipeline phase %r"
%
phase
if
not
printtree
and
isinstance
(
phase
,
PrintTree
):
continue
data
=
phase
(
data
)
data
=
phase
(
data
)
if
DebugFlags
.
debug_verbose_pipeline
:
if
DebugFlags
.
debug_verbose_pipeline
:
print
" %.3f seconds"
%
(
time
()
-
t
)
print
" %.3f seconds"
%
(
time
()
-
t
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
155a4ef5
...
@@ -187,7 +187,7 @@ class PyrexType(BaseType):
...
@@ -187,7 +187,7 @@ class PyrexType(BaseType):
def
needs_nonecheck
(
self
):
def
needs_nonecheck
(
self
):
return
0
return
0
def
public_decl
(
base_code
,
dll_linkage
):
def
public_decl
(
base_code
,
dll_linkage
):
if
dll_linkage
:
if
dll_linkage
:
return
"%s(%s)"
%
(
dll_linkage
,
base_code
)
return
"%s(%s)"
%
(
dll_linkage
,
base_code
)
...
@@ -414,8 +414,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -414,8 +414,7 @@ class MemoryViewSliceType(PyrexType):
def
attributes_known
(
self
):
def
attributes_known
(
self
):
if
self
.
scope
is
None
:
if
self
.
scope
is
None
:
import
Symtab
import
Symtab
,
MemoryView
,
Options
self
.
scope
=
scope
=
Symtab
.
CClassScope
(
self
.
scope
=
scope
=
Symtab
.
CClassScope
(
'mvs_class_'
+
self
.
specialization_suffix
(),
'mvs_class_'
+
self
.
specialization_suffix
(),
...
@@ -424,8 +423,17 @@ class MemoryViewSliceType(PyrexType):
...
@@ -424,8 +423,17 @@ class MemoryViewSliceType(PyrexType):
scope
.
parent_type
=
self
scope
.
parent_type
=
self
scope
.
declare_var
(
'_data'
,
c_char_ptr_type
,
None
,
cname
=
'data'
,
is_cdef
=
1
)
scope
.
declare_var
(
'_data'
,
c_char_ptr_type
,
None
,
cname
=
'data'
,
is_cdef
=
1
)
return
True
def
declare_attribute
(
self
,
attribute
):
import
MemoryView
,
Options
scope
=
self
.
scope
if
attribute
==
'shape'
:
scope
.
declare_var
(
'shape'
,
scope
.
declare_var
(
'shape'
,
c_array_type
(
c_py_ssize_t_type
,
c_array_type
(
c_py_ssize_t_type
,
Options
.
buffer_max_dims
),
Options
.
buffer_max_dims
),
...
@@ -433,6 +441,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -433,6 +441,7 @@ class MemoryViewSliceType(PyrexType):
cname
=
'shape'
,
cname
=
'shape'
,
is_cdef
=
1
)
is_cdef
=
1
)
elif
attribute
==
'strides'
:
scope
.
declare_var
(
'strides'
,
scope
.
declare_var
(
'strides'
,
c_array_type
(
c_py_ssize_t_type
,
c_array_type
(
c_py_ssize_t_type
,
Options
.
buffer_max_dims
),
Options
.
buffer_max_dims
),
...
@@ -440,6 +449,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -440,6 +449,7 @@ class MemoryViewSliceType(PyrexType):
cname
=
'strides'
,
cname
=
'strides'
,
is_cdef
=
1
)
is_cdef
=
1
)
elif
attribute
==
'suboffsets'
:
scope
.
declare_var
(
'suboffsets'
,
scope
.
declare_var
(
'suboffsets'
,
c_array_type
(
c_py_ssize_t_type
,
c_array_type
(
c_py_ssize_t_type
,
Options
.
buffer_max_dims
),
Options
.
buffer_max_dims
),
...
@@ -447,6 +457,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -447,6 +457,7 @@ class MemoryViewSliceType(PyrexType):
cname
=
'suboffsets'
,
cname
=
'suboffsets'
,
is_cdef
=
1
)
is_cdef
=
1
)
elif
attribute
in
(
"copy"
,
"copy_fortran"
):
ndim
=
len
(
self
.
axes
)
ndim
=
len
(
self
.
axes
)
to_axes_c
=
[(
'direct'
,
'contig'
)]
to_axes_c
=
[(
'direct'
,
'contig'
)]
...
...
Cython/Compiler/UtilityCode.py
View file @
155a4ef5
...
@@ -118,7 +118,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
...
@@ -118,7 +118,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
scope_transform
,
pipeline
=
Pipeline
.
insert_into_pipeline
(
pipeline
,
scope_transform
,
before
=
transform
)
before
=
transform
)
(
err
,
tree
)
=
Pipeline
.
run_pipeline
(
pipeline
,
tree
)
(
err
,
tree
)
=
Pipeline
.
run_pipeline
(
pipeline
,
tree
,
printtree
=
False
)
assert
not
err
,
err
assert
not
err
,
err
return
tree
return
tree
...
...
Cython/Utility/MemoryView_C.c
View file @
155a4ef5
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
typedef
struct
{
typedef
struct
{
struct
{{
memview_struct_name
}}
*
memview
;
struct
{{
memview_struct_name
}}
*
memview
;
/* For convenience and faster access */
char
*
data
;
char
*
data
;
Py_ssize_t
shape
[{{
max_dims
}}];
Py_ssize_t
shape
[{{
max_dims
}}];
Py_ssize_t
strides
[{{
max_dims
}}];
Py_ssize_t
strides
[{{
max_dims
}}];
...
@@ -30,9 +29,6 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *);
...
@@ -30,9 +29,6 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *);
#define __Pyx_IS_C_CONTIG 1
#define __Pyx_IS_C_CONTIG 1
#define __Pyx_IS_F_CONTIG 2
#define __Pyx_IS_F_CONTIG 2
/* #define __PYX_MEMSLICE_GETDATA(SLICE) ((char *) SLICE->memview->view->buf) */
static
int
__Pyx_ValidateAndInit_memviewslice
(
struct
__pyx_memoryview_obj
*
memview
,
static
int
__Pyx_ValidateAndInit_memviewslice
(
struct
__pyx_memoryview_obj
*
memview
,
int
*
axes_specs
,
int
c_or_f_flag
,
int
ndim
,
__Pyx_TypeInfo
*
dtype
,
int
*
axes_specs
,
int
c_or_f_flag
,
int
ndim
,
__Pyx_TypeInfo
*
dtype
,
__Pyx_BufFmt_StackElem
stack
[],
__Pyx_memviewslice
*
memviewslice
);
__Pyx_BufFmt_StackElem
stack
[],
__Pyx_memviewslice
*
memviewslice
);
...
@@ -170,7 +166,7 @@ static int __Pyx_ValidateAndInit_memviewslice(
...
@@ -170,7 +166,7 @@ static int __Pyx_ValidateAndInit_memviewslice(
}
}
if
(
spec
&
__Pyx_MEMVIEW_PTR
)
{
if
(
spec
&
__Pyx_MEMVIEW_PTR
)
{
if
(
buf
->
suboffsets
&&
buf
->
suboffsets
[
i
]
<
0
)
{
if
(
!
buf
->
suboffsets
||
(
buf
->
suboffsets
&&
buf
->
suboffsets
[
i
]
<
0
)
)
{
PyErr_Format
(
PyExc_ValueError
,
PyErr_Format
(
PyExc_ValueError
,
"Buffer is not indirectly accessisble in dimension %d."
,
i
);
"Buffer is not indirectly accessisble in dimension %d."
,
i
);
goto
fail
;
goto
fail
;
...
@@ -287,7 +283,6 @@ static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice,
...
@@ -287,7 +283,6 @@ static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice,
struct
{{
memview_struct_name
}}
*
memview
=
memslice
->
memview
;
struct
{{
memview_struct_name
}}
*
memview
=
memslice
->
memview
;
if
(
!
memview
)
if
(
!
memview
)
return
;
/* allow uninitialized memoryview assignment */
return
;
/* allow uninitialized memoryview assignment */
/* __pyx_fatalerror("memoryslice is not initialized (line %d)", lineno); */
if
(
memview
->
acquisition_count
<=
0
)
if
(
memview
->
acquisition_count
<=
0
)
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
__pyx_fatalerror
(
"Acquisition count is %d (line %d)"
,
...
@@ -324,6 +319,7 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
...
@@ -324,6 +319,7 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
last_time
=
(
memview
->
acquisition_count
--
==
1
);
last_time
=
(
memview
->
acquisition_count
--
==
1
);
PyThread_release_lock
(
memview
->
lock
);
PyThread_release_lock
(
memview
->
lock
);
memslice
->
data
=
NULL
;
if
(
last_time
)
{
if
(
last_time
)
{
if
(
have_gil
)
{
if
(
have_gil
)
{
Py_CLEAR
(
memslice
->
memview
);
Py_CLEAR
(
memslice
->
memview
);
...
@@ -332,6 +328,7 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
...
@@ -332,6 +328,7 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
Py_CLEAR
(
memslice
->
memview
);
Py_CLEAR
(
memslice
->
memview
);
PyGILState_Release
(
_gilstate
);
PyGILState_Release
(
_gilstate
);
}
}
}
else
{
memslice
->
memview
=
NULL
;
memslice
->
memview
=
NULL
;
}
}
}
}
...
@@ -466,4 +463,4 @@ int {{set_function}}(const char *itemp, PyObject *obj) {
...
@@ -466,4 +463,4 @@ int {{set_function}}(const char *itemp, PyObject *obj) {
Py_DECREF
(
*
(
PyObject
**
)
itemp
);
Py_DECREF
(
*
(
PyObject
**
)
itemp
);
*
(
PyObject
**
)
itemp
=
obj
;
*
(
PyObject
**
)
itemp
=
obj
;
return
1
;
return
1
;
}
}
\ No newline at end of file
tests/run/cythonarray.pyx
View file @
155a4ef5
...
@@ -5,7 +5,8 @@ from __future__ import unicode_literals
...
@@ -5,7 +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
include
"cythonarrayutil.pxi"
def
contiguity
():
def
contiguity
():
'''
'''
...
@@ -67,26 +68,6 @@ def dont_allocate_buffer():
...
@@ -67,26 +68,6 @@ def dont_allocate_buffer():
result
.
callback_free_data
=
callback
result
.
callback_free_data
=
callback
result
=
None
result
=
None
cdef
void
callback
(
char
*
data
):
print
"callback called %d"
%
<
long
>
data
cdef
create_array
(
shape
,
mode
):
cdef
array
result
=
array
(
shape
,
itemsize
=
sizeof
(
int
),
format
=
'i'
,
mode
=
mode
)
cdef
int
*
data
=
<
int
*>
result
.
data
cdef
int
i
,
j
,
cidx
,
fidx
for
i
in
range
(
shape
[
0
]):
for
j
in
range
(
shape
[
1
]):
cidx
=
i
*
shape
[
1
]
+
j
fidx
=
i
+
j
*
shape
[
0
]
if
mode
==
'fortran'
:
data
[
fidx
]
=
cidx
else
:
data
[
cidx
]
=
cidx
return
result
def
test_cython_array_getbuffer
():
def
test_cython_array_getbuffer
():
"""
"""
>>> test_cython_array_getbuffer()
>>> test_cython_array_getbuffer()
...
...
tests/run/cythonarrayutil.pxi
0 → 100644
View file @
155a4ef5
from
libc.stdlib
cimport
malloc
,
free
cimport
cython
cdef
void
callback
(
char
*
data
):
print
"callback called %d"
%
<
long
>
data
def
create_array
(
shape
,
mode
,
use_callback
=
False
):
cdef
cython
.
array
result
=
cython
.
array
(
shape
,
itemsize
=
sizeof
(
int
),
format
=
'i'
,
mode
=
mode
)
cdef
int
*
data
=
<
int
*>
result
.
data
cdef
int
i
,
j
,
cidx
,
fidx
for
i
in
range
(
shape
[
0
]):
for
j
in
range
(
shape
[
1
]):
cidx
=
i
*
shape
[
1
]
+
j
fidx
=
i
+
j
*
shape
[
0
]
if
mode
==
'fortran'
:
data
[
fidx
]
=
cidx
else
:
data
[
cidx
]
=
cidx
if
use_callback
:
result
.
callback_free_data
=
callback
return
result
tests/run/memslice.pyx
View file @
155a4ef5
...
@@ -23,6 +23,7 @@ def testcase(func):
...
@@ -23,6 +23,7 @@ def testcase(func):
include
"mockbuffers.pxi"
include
"mockbuffers.pxi"
include
"cythonarrayutil.pxi"
#
#
# Buffer acquire and release tests
# Buffer acquire and release tests
...
@@ -1083,12 +1084,14 @@ def buffer_nogil():
...
@@ -1083,12 +1084,14 @@ def buffer_nogil():
#
#
### Test cdef functions
### Test cdef functions
#
#
cdef
cdef
_function
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
ObjectMockBuffer
(
None
,
[[
"spam"
],[
"ham"
],[
"eggs"
]])):
objs
=
[[
"spam"
],
[
"ham"
],
[
"eggs"
]]
cdef
cdef
_function
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
ObjectMockBuffer
(
None
,
objs
)):
print
'cdef called'
print
'cdef called'
print
buf1
[
6
],
buf2
[
1
,
0
]
print
buf1
[
6
],
buf2
[
1
,
0
]
buf2
[
1
,
0
]
=
"eggs"
buf2
[
1
,
0
]
=
"eggs"
@
testcase
def
test_cdef_function
(
o1
,
o2
=
None
):
def
test_cdef_function
(
o1
,
o2
=
None
):
"""
"""
>>> A = IntMockBuffer("A", range(10))
>>> A = IntMockBuffer("A", range(10))
...
@@ -1101,19 +1104,22 @@ def test_cdef_function(o1, o2=None):
...
@@ -1101,19 +1104,22 @@ def test_cdef_function(o1, o2=None):
cdef called
cdef called
6 eggs
6 eggs
released A
released A
>>> B = ObjectMockBuffer("B", range(25), shape=(5, 5))
>>> L = [[x] for x in range(25)]
>>> B = ObjectMockBuffer("B", L, shape=(5, 5))
>>> test_cdef_function(A, B)
>>> test_cdef_function(A, B)
acquired A
acquired A
acquired B
cdef called
cdef called
6 eggs
6 eggs
released A
released A
released B
acquired A
acquired A
acquired B
cdef called
cdef called
6 eggs
6 eggs
released A
released A
acquired A
acquired B
cdef called
6 1
released A
released B
released B
"""
"""
cdef
_function
(
o1
)
cdef
_function
(
o1
)
...
@@ -1122,15 +1128,15 @@ def test_cdef_function(o1, o2=None):
...
@@ -1122,15 +1128,15 @@ def test_cdef_function(o1, o2=None):
if
o2
:
if
o2
:
cdef
_function
(
o1
,
o2
)
cdef
_function
(
o1
,
o2
)
cdef
int
[:]
global_A
=
IntMockBuffer
(
"A"
,
range
(
10
))
cdef
int
[:]
global_A
=
IntMockBuffer
(
"Global_A"
,
range
(
10
))
cdef
object
[::
view
.
indirect
,
:]
global_B
=
ObjectMockBuffer
(
cdef
object
[::
view
.
indirect
,
:]
global_B
=
ObjectMockBuffer
(
None
,
objs
)
None
,
[[
"spam"
],[
"ham"
],[
"eggs"
]])
cdef
cdef
_function2
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
global_B
):
cdef
cdef
_function2
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
global_B
):
print
'cdef2 called'
print
'cdef2 called'
print
buf1
[
6
],
buf2
[
1
,
0
]
print
buf1
[
6
],
buf2
[
1
,
0
]
buf2
[
1
,
0
]
=
"eggs"
buf2
[
1
,
0
]
=
"eggs"
@
testcase
def
test_cdef_function2
():
def
test_cdef_function2
():
"""
"""
>>> test_cdef_function2()
>>> test_cdef_function2()
...
@@ -1151,3 +1157,76 @@ def test_cdef_function2():
...
@@ -1151,3 +1157,76 @@ def test_cdef_function2():
print
global_B
[
1
,
0
]
print
global_B
[
1
,
0
]
cdef
_function2
(
global_A
,
global_B
)
cdef
_function2
(
global_A
,
global_B
)
@
testcase
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
cdef
int
[::
view
.
generic
,
::
view
.
generic
,
:]
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
)
@
testcase
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
cdef
int
[:,
:]
b
=
a
[
-
5
:,
1
,
1
::
2
]
cdef
int
[:,
:]
c
=
b
[
4
:
1
:
-
1
,
::
-
1
]
cdef
int
[:]
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
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