Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
30d43c49
Commit
30d43c49
authored
Apr 14, 2017
by
Cris Luengo
Committed by
Dean Moldovan
May 08, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Now `shape`, `size`, `ndims` and `itemsize` are also signed integers.
parent
b68959e8
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
113 additions
and
111 deletions
+113
-111
docs/advanced/pycpp/numpy.rst
+15
-18
include/pybind11/buffer_info.h
+12
-12
include/pybind11/class_support.h
+4
-6
include/pybind11/eigen.h
+5
-5
include/pybind11/numpy.h
+0
-0
include/pybind11/pytypes.h
+5
-5
include/pybind11/stl_bind.h
+7
-7
tests/test_buffers.cpp
+21
-21
tests/test_eigen.py
+2
-2
tests/test_numpy_array.cpp
+31
-29
tests/test_numpy_array.py
+6
-1
tests/test_numpy_dtypes.cpp
+3
-3
tests/test_numpy_vectorize.cpp
+2
-2
No files found.
docs/advanced/pycpp/numpy.rst
View file @
30d43c49
...
@@ -57,10 +57,10 @@ specification.
...
@@ -57,10 +57,10 @@ specification.
struct buffer_info {
struct buffer_info {
void *ptr;
void *ptr;
size_t itemsize;
s
s
ize_t itemsize;
std::string format;
std::string format;
in
t ndim;
ssize_
t ndim;
std::vector<size_t> shape;
std::vector<s
s
ize_t> shape;
std::vector<ssize_t> strides;
std::vector<ssize_t> strides;
};
};
...
@@ -95,8 +95,8 @@ buffer objects (e.g. a NumPy matrix).
...
@@ -95,8 +95,8 @@ buffer objects (e.g. a NumPy matrix).
throw std::runtime_error("Incompatible buffer dimension!");
throw std::runtime_error("Incompatible buffer dimension!");
auto strides = Strides(
auto strides = Strides(
info.strides[rowMajor ? 0 : 1] / sizeof(Scalar),
info.strides[rowMajor ? 0 : 1] /
(py::ssize_t)
sizeof(Scalar),
info.strides[rowMajor ? 1 : 0] / sizeof(Scalar));
info.strides[rowMajor ? 1 : 0] /
(py::ssize_t)
sizeof(Scalar));
auto map = Eigen::Map<Matrix, 0, Strides>(
auto map = Eigen::Map<Matrix, 0, Strides>(
static_cat<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);
static_cat<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);
...
@@ -113,15 +113,12 @@ as follows:
...
@@ -113,15 +113,12 @@ as follows:
return py::buffer_info(
return py::buffer_info(
m.data(), /* Pointer to buffer */
m.data(), /* Pointer to buffer */
sizeof(Scalar), /* Size of one scalar */
sizeof(Scalar), /* Size of one scalar */
/* Python struct-style format descriptor */
py::format_descriptor<Scalar>::format(), /* Python struct-style format descriptor */
py::format_descriptor<Scalar>::format(),
2, /* Number of dimensions */
/* Number of dimensions */
{ m.rows(), m.cols() }, /* Buffer dimensions */
2,
/* Buffer dimensions */
{ m.rows(), m.cols() },
/* Strides (in bytes) for each index */
{ sizeof(Scalar) * (rowMajor ? m.cols() : 1),
{ sizeof(Scalar) * (rowMajor ? m.cols() : 1),
sizeof(Scalar) * (rowMajor ? 1 : m.rows()) }
sizeof(Scalar) * (rowMajor ? 1 : m.rows()) }
/* Strides (in bytes) for each index */
);
);
})
})
...
@@ -321,17 +318,17 @@ where ``N`` gives the required dimensionality of the array:
...
@@ -321,17 +318,17 @@ where ``N`` gives the required dimensionality of the array:
m.def("sum_3d", [](py::array_t<double> x) {
m.def("sum_3d", [](py::array_t<double> x) {
auto r = x.unchecked<3>(); // x must have ndim = 3; can be non-writeable
auto r = x.unchecked<3>(); // x must have ndim = 3; can be non-writeable
double sum = 0;
double sum = 0;
for (size_t i = 0; i < r.shape(0); i++)
for (s
s
ize_t i = 0; i < r.shape(0); i++)
for (size_t j = 0; j < r.shape(1); j++)
for (s
s
ize_t j = 0; j < r.shape(1); j++)
for (size_t k = 0; k < r.shape(2); k++)
for (s
s
ize_t k = 0; k < r.shape(2); k++)
sum += r(i, j, k);
sum += r(i, j, k);
return sum;
return sum;
});
});
m.def("increment_3d", [](py::array_t<double> x) {
m.def("increment_3d", [](py::array_t<double> x) {
auto r = x.mutable_unchecked<3>(); // Will throw if ndim != 3 or flags.writeable is false
auto r = x.mutable_unchecked<3>(); // Will throw if ndim != 3 or flags.writeable is false
for (size_t i = 0; i < r.shape(0); i++)
for (s
s
ize_t i = 0; i < r.shape(0); i++)
for (size_t j = 0; j < r.shape(1); j++)
for (s
s
ize_t j = 0; j < r.shape(1); j++)
for (size_t k = 0; k < r.shape(2); k++)
for (s
s
ize_t k = 0; k < r.shape(2); k++)
r(i, j, k) += 1.0;
r(i, j, k) += 1.0;
}, py::arg().noconvert());
}, py::arg().noconvert());
...
...
include/pybind11/buffer_info.h
View file @
30d43c49
...
@@ -16,30 +16,30 @@ NAMESPACE_BEGIN(pybind11)
...
@@ -16,30 +16,30 @@ NAMESPACE_BEGIN(pybind11)
/// Information record describing a Python buffer object
/// Information record describing a Python buffer object
struct
buffer_info
{
struct
buffer_info
{
void
*
ptr
=
nullptr
;
// Pointer to the underlying storage
void
*
ptr
=
nullptr
;
// Pointer to the underlying storage
size_t
itemsize
=
0
;
// Size of individual items in bytes
s
s
ize_t
itemsize
=
0
;
// Size of individual items in bytes
size_t
size
=
0
;
// Total number of entries
s
s
ize_t
size
=
0
;
// Total number of entries
std
::
string
format
;
// For homogeneous buffers, this should be set to format_descriptor<T>::format()
std
::
string
format
;
// For homogeneous buffers, this should be set to format_descriptor<T>::format()
size_t
ndim
=
0
;
// Number of dimensions
s
s
ize_t
ndim
=
0
;
// Number of dimensions
std
::
vector
<
size_t
>
shape
;
// Shape of the tensor (1 entry per dimension)
std
::
vector
<
s
s
ize_t
>
shape
;
// Shape of the tensor (1 entry per dimension)
std
::
vector
<
ssize_t
>
strides
;
// Number of entries between adjacent entries (for each per dimension)
std
::
vector
<
ssize_t
>
strides
;
// Number of entries between adjacent entries (for each per dimension)
buffer_info
()
{
}
buffer_info
()
{
}
buffer_info
(
void
*
ptr
,
s
ize_t
itemsize
,
const
std
::
string
&
format
,
size_t
ndim
,
buffer_info
(
void
*
ptr
,
s
size_t
itemsize
,
const
std
::
string
&
format
,
s
size_t
ndim
,
detail
::
any_container
<
size_t
>
shape_in
,
detail
::
any_container
<
ssize_t
>
strides_in
)
detail
::
any_container
<
s
s
ize_t
>
shape_in
,
detail
::
any_container
<
ssize_t
>
strides_in
)
:
ptr
(
ptr
),
itemsize
(
itemsize
),
size
(
1
),
format
(
format
),
ndim
(
ndim
),
:
ptr
(
ptr
),
itemsize
(
itemsize
),
size
(
1
),
format
(
format
),
ndim
(
ndim
),
shape
(
std
::
move
(
shape_in
)),
strides
(
std
::
move
(
strides_in
))
{
shape
(
std
::
move
(
shape_in
)),
strides
(
std
::
move
(
strides_in
))
{
if
(
ndim
!=
shape
.
size
()
||
ndim
!=
strides
.
size
())
if
(
ndim
!=
(
ssize_t
)
shape
.
size
()
||
ndim
!=
(
ssize_t
)
strides
.
size
())
pybind11_fail
(
"buffer_info: ndim doesn't match shape and/or strides length"
);
pybind11_fail
(
"buffer_info: ndim doesn't match shape and/or strides length"
);
for
(
size_t
i
=
0
;
i
<
ndim
;
++
i
)
for
(
size_t
i
=
0
;
i
<
(
size_t
)
ndim
;
++
i
)
size
*=
shape
[
i
];
size
*=
shape
[
i
];
}
}
buffer_info
(
void
*
ptr
,
s
ize_t
itemsize
,
const
std
::
string
&
format
,
size_t
size
)
buffer_info
(
void
*
ptr
,
s
size_t
itemsize
,
const
std
::
string
&
format
,
s
size_t
size
)
:
buffer_info
(
ptr
,
itemsize
,
format
,
1
,
{
size
},
{
itemsize
})
{
}
:
buffer_info
(
ptr
,
itemsize
,
format
,
1
,
{
size
},
{
itemsize
})
{
}
explicit
buffer_info
(
Py_buffer
*
view
,
bool
ownview
=
true
)
explicit
buffer_info
(
Py_buffer
*
view
,
bool
ownview
=
true
)
:
buffer_info
(
view
->
buf
,
(
size_t
)
view
->
itemsize
,
view
->
format
,
(
size_t
)
view
->
ndim
,
:
buffer_info
(
view
->
buf
,
view
->
itemsize
,
view
->
format
,
view
->
ndim
,
{
view
->
shape
,
view
->
shape
+
view
->
ndim
},
{
view
->
strides
,
view
->
strides
+
view
->
ndim
})
{
{
view
->
shape
,
view
->
shape
+
view
->
ndim
},
{
view
->
strides
,
view
->
strides
+
view
->
ndim
})
{
this
->
view
=
view
;
this
->
view
=
view
;
this
->
ownview
=
ownview
;
this
->
ownview
=
ownview
;
...
@@ -78,13 +78,13 @@ NAMESPACE_BEGIN(detail)
...
@@ -78,13 +78,13 @@ NAMESPACE_BEGIN(detail)
template
<
typename
T
,
typename
SFINAE
=
void
>
struct
compare_buffer_info
{
template
<
typename
T
,
typename
SFINAE
=
void
>
struct
compare_buffer_info
{
static
bool
compare
(
const
buffer_info
&
b
)
{
static
bool
compare
(
const
buffer_info
&
b
)
{
return
b
.
format
==
format_descriptor
<
T
>::
format
()
&&
b
.
itemsize
==
sizeof
(
T
);
return
b
.
format
==
format_descriptor
<
T
>::
format
()
&&
b
.
itemsize
==
(
ssize_t
)
sizeof
(
T
);
}
}
};
};
template
<
typename
T
>
struct
compare_buffer_info
<
T
,
detail
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
>>
{
template
<
typename
T
>
struct
compare_buffer_info
<
T
,
detail
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
>>
{
static
bool
compare
(
const
buffer_info
&
b
)
{
static
bool
compare
(
const
buffer_info
&
b
)
{
return
b
.
itemsize
==
sizeof
(
T
)
&&
(
b
.
format
==
format_descriptor
<
T
>::
value
||
return
(
size_t
)
b
.
itemsize
==
sizeof
(
T
)
&&
(
b
.
format
==
format_descriptor
<
T
>::
value
||
((
sizeof
(
T
)
==
sizeof
(
long
))
&&
b
.
format
==
(
std
::
is_unsigned
<
T
>::
value
?
"L"
:
"l"
))
||
((
sizeof
(
T
)
==
sizeof
(
long
))
&&
b
.
format
==
(
std
::
is_unsigned
<
T
>::
value
?
"L"
:
"l"
))
||
((
sizeof
(
T
)
==
sizeof
(
size_t
))
&&
b
.
format
==
(
std
::
is_unsigned
<
T
>::
value
?
"N"
:
"n"
)));
((
sizeof
(
T
)
==
sizeof
(
size_t
))
&&
b
.
format
==
(
std
::
is_unsigned
<
T
>::
value
?
"N"
:
"n"
)));
}
}
...
...
include/pybind11/class_support.h
View file @
30d43c49
...
@@ -433,7 +433,7 @@ inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
...
@@ -433,7 +433,7 @@ inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
#endif
#endif
type
->
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
type
->
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
type
->
tp_dictoffset
=
type
->
tp_basicsize
;
// place dict at the end
type
->
tp_dictoffset
=
type
->
tp_basicsize
;
// place dict at the end
type
->
tp_basicsize
+=
(
Py_
ssize_t
)
sizeof
(
PyObject
*
);
// and allocate enough space for it
type
->
tp_basicsize
+=
(
ssize_t
)
sizeof
(
PyObject
*
);
// and allocate enough space for it
type
->
tp_traverse
=
pybind11_traverse
;
type
->
tp_traverse
=
pybind11_traverse
;
type
->
tp_clear
=
pybind11_clear
;
type
->
tp_clear
=
pybind11_clear
;
...
@@ -459,18 +459,16 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
...
@@ -459,18 +459,16 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
view
->
ndim
=
1
;
view
->
ndim
=
1
;
view
->
internal
=
info
;
view
->
internal
=
info
;
view
->
buf
=
info
->
ptr
;
view
->
buf
=
info
->
ptr
;
view
->
itemsize
=
(
Py_ssize_t
)
info
->
itemsize
;
view
->
itemsize
=
info
->
itemsize
;
view
->
len
=
view
->
itemsize
;
view
->
len
=
view
->
itemsize
;
for
(
auto
s
:
info
->
shape
)
for
(
auto
s
:
info
->
shape
)
view
->
len
*=
(
Py_ssize_t
)
s
;
view
->
len
*=
s
;
if
((
flags
&
PyBUF_FORMAT
)
==
PyBUF_FORMAT
)
if
((
flags
&
PyBUF_FORMAT
)
==
PyBUF_FORMAT
)
view
->
format
=
const_cast
<
char
*>
(
info
->
format
.
c_str
());
view
->
format
=
const_cast
<
char
*>
(
info
->
format
.
c_str
());
if
((
flags
&
PyBUF_STRIDES
)
==
PyBUF_STRIDES
)
{
if
((
flags
&
PyBUF_STRIDES
)
==
PyBUF_STRIDES
)
{
view
->
ndim
=
(
int
)
info
->
ndim
;
view
->
ndim
=
(
int
)
info
->
ndim
;
view
->
strides
=
&
info
->
strides
[
0
];
view
->
strides
=
&
info
->
strides
[
0
];
// Next is a pointer cast, let's make sure it's safe.
view
->
shape
=
&
info
->
shape
[
0
];
static_assert
(
sizeof
(
Py_ssize_t
)
==
sizeof
(
info
->
shape
[
0
]),
"sizeof(Py_ssize_t) != sizeof(size_t)"
);
view
->
shape
=
(
Py_ssize_t
*
)
&
info
->
shape
[
0
];
}
}
Py_INCREF
(
view
->
obj
);
Py_INCREF
(
view
->
obj
);
return
0
;
return
0
;
...
...
include/pybind11/eigen.h
View file @
30d43c49
...
@@ -68,7 +68,7 @@ template <typename T> using is_eigen_other = all_of<
...
@@ -68,7 +68,7 @@ template <typename T> using is_eigen_other = all_of<
template
<
bool
EigenRowMajor
>
struct
EigenConformable
{
template
<
bool
EigenRowMajor
>
struct
EigenConformable
{
bool
conformable
=
false
;
bool
conformable
=
false
;
EigenIndex
rows
=
0
,
cols
=
0
;
EigenIndex
rows
=
0
,
cols
=
0
;
EigenDStride
stride
{
0
,
0
};
// Only valid if negativestride
e
s is false!
EigenDStride
stride
{
0
,
0
};
// Only valid if negativestrides is false!
bool
negativestrides
=
false
;
// If true, do not use stride!
bool
negativestrides
=
false
;
// If true, do not use stride!
EigenConformable
(
bool
fits
=
false
)
:
conformable
{
fits
}
{}
EigenConformable
(
bool
fits
=
false
)
:
conformable
{
fits
}
{}
...
@@ -207,7 +207,7 @@ template <typename Type_> struct EigenProps {
...
@@ -207,7 +207,7 @@ template <typename Type_> struct EigenProps {
// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data,
// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data,
// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array.
// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array.
template
<
typename
props
>
handle
eigen_array_cast
(
typename
props
::
Type
const
&
src
,
handle
base
=
handle
(),
bool
writeable
=
true
)
{
template
<
typename
props
>
handle
eigen_array_cast
(
typename
props
::
Type
const
&
src
,
handle
base
=
handle
(),
bool
writeable
=
true
)
{
constexpr
size_t
elem_size
=
sizeof
(
typename
props
::
Scalar
);
constexpr
s
s
ize_t
elem_size
=
sizeof
(
typename
props
::
Scalar
);
array
a
;
array
a
;
if
(
props
::
vector
)
if
(
props
::
vector
)
a
=
array
({
src
.
size
()
},
{
elem_size
*
src
.
innerStride
()
},
src
.
data
(),
base
);
a
=
array
({
src
.
size
()
},
{
elem_size
*
src
.
innerStride
()
},
src
.
data
(),
base
);
...
@@ -581,9 +581,9 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
...
@@ -581,9 +581,9 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
object
matrix_type
=
module
::
import
(
"scipy.sparse"
).
attr
(
object
matrix_type
=
module
::
import
(
"scipy.sparse"
).
attr
(
rowMajor
?
"csr_matrix"
:
"csc_matrix"
);
rowMajor
?
"csr_matrix"
:
"csc_matrix"
);
array
data
(
(
size_t
)
src
.
nonZeros
(),
src
.
valuePtr
());
array
data
(
src
.
nonZeros
(),
src
.
valuePtr
());
array
outerIndices
((
size_t
)
(
rowMajor
?
src
.
rows
()
:
src
.
cols
())
+
1
,
src
.
outerIndexPtr
());
array
outerIndices
((
rowMajor
?
src
.
rows
()
:
src
.
cols
())
+
1
,
src
.
outerIndexPtr
());
array
innerIndices
(
(
size_t
)
src
.
nonZeros
(),
src
.
innerIndexPtr
());
array
innerIndices
(
src
.
nonZeros
(),
src
.
innerIndexPtr
());
return
matrix_type
(
return
matrix_type
(
std
::
make_tuple
(
data
,
innerIndices
,
outerIndices
),
std
::
make_tuple
(
data
,
innerIndices
,
outerIndices
),
...
...
include/pybind11/numpy.h
View file @
30d43c49
This diff is collapsed.
Click to expand it.
include/pybind11/pytypes.h
View file @
30d43c49
...
@@ -1165,15 +1165,15 @@ public:
...
@@ -1165,15 +1165,15 @@ public:
static
std
::
vector
<
Py_ssize_t
>
py_strides
{
};
static
std
::
vector
<
Py_ssize_t
>
py_strides
{
};
static
std
::
vector
<
Py_ssize_t
>
py_shape
{
};
static
std
::
vector
<
Py_ssize_t
>
py_shape
{
};
buf
.
buf
=
info
.
ptr
;
buf
.
buf
=
info
.
ptr
;
buf
.
itemsize
=
(
Py_ssize_t
)
info
.
itemsize
;
buf
.
itemsize
=
info
.
itemsize
;
buf
.
format
=
const_cast
<
char
*>
(
info
.
format
.
c_str
());
buf
.
format
=
const_cast
<
char
*>
(
info
.
format
.
c_str
());
buf
.
ndim
=
(
int
)
info
.
ndim
;
buf
.
ndim
=
(
int
)
info
.
ndim
;
buf
.
len
=
(
Py_ssize_t
)
info
.
size
;
buf
.
len
=
info
.
size
;
py_strides
.
clear
();
py_strides
.
clear
();
py_shape
.
clear
();
py_shape
.
clear
();
for
(
size_t
i
=
0
;
i
<
info
.
ndim
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
(
size_t
)
info
.
ndim
;
++
i
)
{
py_strides
.
push_back
(
(
Py_ssize_t
)
info
.
strides
[
i
]);
py_strides
.
push_back
(
info
.
strides
[
i
]);
py_shape
.
push_back
(
(
Py_ssize_t
)
info
.
shape
[
i
]);
py_shape
.
push_back
(
info
.
shape
[
i
]);
}
}
buf
.
strides
=
py_strides
.
data
();
buf
.
strides
=
py_strides
.
data
();
buf
.
shape
=
py_shape
.
data
();
buf
.
shape
=
py_shape
.
data
();
...
...
include/pybind11/stl_bind.h
View file @
30d43c49
...
@@ -345,21 +345,21 @@ vector_buffer(Class_& cl) {
...
@@ -345,21 +345,21 @@ vector_buffer(Class_& cl) {
format_descriptor
<
T
>::
format
();
format_descriptor
<
T
>::
format
();
cl
.
def_buffer
([](
Vector
&
v
)
->
buffer_info
{
cl
.
def_buffer
([](
Vector
&
v
)
->
buffer_info
{
return
buffer_info
(
v
.
data
(),
s
izeof
(
T
),
format_descriptor
<
T
>::
format
(),
1
,
{
v
.
size
()},
{
sizeof
(
T
)});
return
buffer_info
(
v
.
data
(),
s
tatic_cast
<
ssize_t
>
(
sizeof
(
T
)
),
format_descriptor
<
T
>::
format
(),
1
,
{
v
.
size
()},
{
sizeof
(
T
)});
});
});
cl
.
def
(
"__init__"
,
[](
Vector
&
vec
,
buffer
buf
)
{
cl
.
def
(
"__init__"
,
[](
Vector
&
vec
,
buffer
buf
)
{
auto
info
=
buf
.
request
();
auto
info
=
buf
.
request
();
if
(
info
.
ndim
!=
1
||
info
.
strides
[
0
]
<=
0
||
info
.
strides
[
0
]
%
static_cast
<
ssize_t
>
(
sizeof
(
T
)))
if
(
info
.
ndim
!=
1
||
info
.
strides
[
0
]
%
static_cast
<
ssize_t
>
(
sizeof
(
T
)))
throw
type_error
(
"Only valid 1D buffers can be copied to a vector"
);
throw
type_error
(
"Only valid 1D buffers can be copied to a vector"
);
if
(
!
detail
::
compare_buffer_info
<
T
>::
compare
(
info
)
||
sizeof
(
T
)
!=
info
.
itemsize
)
if
(
!
detail
::
compare_buffer_info
<
T
>::
compare
(
info
)
||
(
ssize_t
)
sizeof
(
T
)
!=
info
.
itemsize
)
throw
type_error
(
"Format mismatch (Python: "
+
info
.
format
+
" C++: "
+
format_descriptor
<
T
>::
format
()
+
")"
);
throw
type_error
(
"Format mismatch (Python: "
+
info
.
format
+
" C++: "
+
format_descriptor
<
T
>::
format
()
+
")"
);
new
(
&
vec
)
Vector
();
new
(
&
vec
)
Vector
();
vec
.
reserve
(
info
.
shape
[
0
]);
vec
.
reserve
(
(
size_t
)
info
.
shape
[
0
]);
T
*
p
=
static_cast
<
T
*>
(
info
.
ptr
);
T
*
p
=
static_cast
<
T
*>
(
info
.
ptr
);
auto
step
=
info
.
strides
[
0
]
/
static_cast
<
ssize_t
>
(
sizeof
(
T
));
ssize_t
step
=
info
.
strides
[
0
]
/
static_cast
<
ssize_t
>
(
sizeof
(
T
));
T
*
end
=
p
+
static_cast
<
ssize_t
>
(
info
.
shape
[
0
])
*
step
;
T
*
end
=
p
+
info
.
shape
[
0
]
*
step
;
for
(;
p
<
end
;
p
+=
step
)
for
(;
p
!=
end
;
p
+=
step
)
vec
.
push_back
(
*
p
);
vec
.
push_back
(
*
p
);
});
});
...
...
tests/test_buffers.cpp
View file @
30d43c49
...
@@ -12,16 +12,16 @@
...
@@ -12,16 +12,16 @@
class
Matrix
{
class
Matrix
{
public
:
public
:
Matrix
(
s
ize_t
rows
,
size_t
cols
)
:
m_rows
(
rows
),
m_cols
(
cols
)
{
Matrix
(
s
size_t
rows
,
s
size_t
cols
)
:
m_rows
(
rows
),
m_cols
(
cols
)
{
print_created
(
this
,
std
::
to_string
(
m_rows
)
+
"x"
+
std
::
to_string
(
m_cols
)
+
" matrix"
);
print_created
(
this
,
std
::
to_string
(
m_rows
)
+
"x"
+
std
::
to_string
(
m_cols
)
+
" matrix"
);
m_data
=
new
float
[
rows
*
cols
];
m_data
=
new
float
[
(
size_t
)
(
rows
*
cols
)
];
memset
(
m_data
,
0
,
sizeof
(
float
)
*
rows
*
cols
);
memset
(
m_data
,
0
,
sizeof
(
float
)
*
(
size_t
)
(
rows
*
cols
)
);
}
}
Matrix
(
const
Matrix
&
s
)
:
m_rows
(
s
.
m_rows
),
m_cols
(
s
.
m_cols
)
{
Matrix
(
const
Matrix
&
s
)
:
m_rows
(
s
.
m_rows
),
m_cols
(
s
.
m_cols
)
{
print_copy_created
(
this
,
std
::
to_string
(
m_rows
)
+
"x"
+
std
::
to_string
(
m_cols
)
+
" matrix"
);
print_copy_created
(
this
,
std
::
to_string
(
m_rows
)
+
"x"
+
std
::
to_string
(
m_cols
)
+
" matrix"
);
m_data
=
new
float
[
m_rows
*
m_cols
];
m_data
=
new
float
[
(
size_t
)
(
m_rows
*
m_cols
)
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_rows
*
m_cols
);
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
(
size_t
)
(
m_rows
*
m_cols
)
);
}
}
Matrix
(
Matrix
&&
s
)
:
m_rows
(
s
.
m_rows
),
m_cols
(
s
.
m_cols
),
m_data
(
s
.
m_data
)
{
Matrix
(
Matrix
&&
s
)
:
m_rows
(
s
.
m_rows
),
m_cols
(
s
.
m_cols
),
m_data
(
s
.
m_data
)
{
...
@@ -41,8 +41,8 @@ public:
...
@@ -41,8 +41,8 @@ public:
delete
[]
m_data
;
delete
[]
m_data
;
m_rows
=
s
.
m_rows
;
m_rows
=
s
.
m_rows
;
m_cols
=
s
.
m_cols
;
m_cols
=
s
.
m_cols
;
m_data
=
new
float
[
m_rows
*
m_cols
];
m_data
=
new
float
[
(
size_t
)
(
m_rows
*
m_cols
)
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_rows
*
m_cols
);
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
(
size_t
)
(
m_rows
*
m_cols
)
);
return
*
this
;
return
*
this
;
}
}
...
@@ -56,47 +56,47 @@ public:
...
@@ -56,47 +56,47 @@ public:
return
*
this
;
return
*
this
;
}
}
float
operator
()(
s
ize_t
i
,
size_t
j
)
const
{
float
operator
()(
s
size_t
i
,
s
size_t
j
)
const
{
return
m_data
[
i
*
m_cols
+
j
];
return
m_data
[
(
size_t
)
(
i
*
m_cols
+
j
)
];
}
}
float
&
operator
()(
s
ize_t
i
,
size_t
j
)
{
float
&
operator
()(
s
size_t
i
,
s
size_t
j
)
{
return
m_data
[
i
*
m_cols
+
j
];
return
m_data
[
(
size_t
)
(
i
*
m_cols
+
j
)
];
}
}
float
*
data
()
{
return
m_data
;
}
float
*
data
()
{
return
m_data
;
}
size_t
rows
()
const
{
return
m_rows
;
}
s
s
ize_t
rows
()
const
{
return
m_rows
;
}
size_t
cols
()
const
{
return
m_cols
;
}
s
s
ize_t
cols
()
const
{
return
m_cols
;
}
private
:
private
:
size_t
m_rows
;
s
s
ize_t
m_rows
;
size_t
m_cols
;
s
s
ize_t
m_cols
;
float
*
m_data
;
float
*
m_data
;
};
};
test_initializer
buffers
([](
py
::
module
&
m
)
{
test_initializer
buffers
([](
py
::
module
&
m
)
{
py
::
class_
<
Matrix
>
mtx
(
m
,
"Matrix"
,
py
::
buffer_protocol
());
py
::
class_
<
Matrix
>
mtx
(
m
,
"Matrix"
,
py
::
buffer_protocol
());
mtx
.
def
(
py
::
init
<
s
ize_t
,
size_t
>
())
mtx
.
def
(
py
::
init
<
s
size_t
,
s
size_t
>
())
/// Construct from a buffer
/// Construct from a buffer
.
def
(
"__init__"
,
[](
Matrix
&
v
,
py
::
buffer
b
)
{
.
def
(
"__init__"
,
[](
Matrix
&
v
,
py
::
buffer
b
)
{
py
::
buffer_info
info
=
b
.
request
();
py
::
buffer_info
info
=
b
.
request
();
if
(
info
.
format
!=
py
::
format_descriptor
<
float
>::
format
()
||
info
.
ndim
!=
2
)
if
(
info
.
format
!=
py
::
format_descriptor
<
float
>::
format
()
||
info
.
ndim
!=
2
)
throw
std
::
runtime_error
(
"Incompatible buffer format!"
);
throw
std
::
runtime_error
(
"Incompatible buffer format!"
);
new
(
&
v
)
Matrix
(
info
.
shape
[
0
],
info
.
shape
[
1
]);
new
(
&
v
)
Matrix
(
info
.
shape
[
0
],
info
.
shape
[
1
]);
memcpy
(
v
.
data
(),
info
.
ptr
,
sizeof
(
float
)
*
v
.
rows
()
*
v
.
cols
(
));
memcpy
(
v
.
data
(),
info
.
ptr
,
sizeof
(
float
)
*
(
size_t
)
(
v
.
rows
()
*
v
.
cols
()
));
})
})
.
def
(
"rows"
,
&
Matrix
::
rows
)
.
def
(
"rows"
,
&
Matrix
::
rows
)
.
def
(
"cols"
,
&
Matrix
::
cols
)
.
def
(
"cols"
,
&
Matrix
::
cols
)
/// Bare bones interface
/// Bare bones interface
.
def
(
"__getitem__"
,
[](
const
Matrix
&
m
,
std
::
pair
<
s
ize_t
,
size_t
>
i
)
{
.
def
(
"__getitem__"
,
[](
const
Matrix
&
m
,
std
::
pair
<
s
size_t
,
s
size_t
>
i
)
{
if
(
i
.
first
>=
m
.
rows
()
||
i
.
second
>=
m
.
cols
())
if
(
i
.
first
>=
m
.
rows
()
||
i
.
second
>=
m
.
cols
())
throw
py
::
index_error
();
throw
py
::
index_error
();
return
m
(
i
.
first
,
i
.
second
);
return
m
(
i
.
first
,
i
.
second
);
})
})
.
def
(
"__setitem__"
,
[](
Matrix
&
m
,
std
::
pair
<
s
ize_t
,
size_t
>
i
,
float
v
)
{
.
def
(
"__setitem__"
,
[](
Matrix
&
m
,
std
::
pair
<
s
size_t
,
s
size_t
>
i
,
float
v
)
{
if
(
i
.
first
>=
m
.
rows
()
||
i
.
second
>=
m
.
cols
())
if
(
i
.
first
>=
m
.
rows
()
||
i
.
second
>=
m
.
cols
())
throw
py
::
index_error
();
throw
py
::
index_error
();
m
(
i
.
first
,
i
.
second
)
=
v
;
m
(
i
.
first
,
i
.
second
)
=
v
;
...
@@ -109,8 +109,8 @@ test_initializer buffers([](py::module &m) {
...
@@ -109,8 +109,8 @@ test_initializer buffers([](py::module &m) {
py
::
format_descriptor
<
float
>::
format
(),
/* Python struct-style format descriptor */
py
::
format_descriptor
<
float
>::
format
(),
/* Python struct-style format descriptor */
2
,
/* Number of dimensions */
2
,
/* Number of dimensions */
{
m
.
rows
(),
m
.
cols
()
},
/* Buffer dimensions */
{
m
.
rows
(),
m
.
cols
()
},
/* Buffer dimensions */
{
s
tatic_cast
<
ssize_t
>
(
sizeof
(
float
)
*
m
.
rows
()),
/* Strides (in bytes) for each index */
{
s
izeof
(
float
)
*
size_t
(
m
.
rows
()),
/* Strides (in bytes) for each index */
s
tatic_cast
<
ssize_t
>
(
sizeof
(
float
)
)
}
s
izeof
(
float
)
}
);
);
})
})
;
;
...
...
tests/test_eigen.py
View file @
30d43c49
...
@@ -186,7 +186,7 @@ def test_negative_stride_from_python(msg):
...
@@ -186,7 +186,7 @@ def test_negative_stride_from_python(msg):
double_threer
(
second_row
)
double_threer
(
second_row
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
msg
(
excinfo
.
value
)
==
"""
double_threer(): incompatible function arguments. The following argument types are supported:
double_threer(): incompatible function arguments. The following argument types are supported:
1. (
numpy.ndarray[float32[1, 3], flags.writeable]) -> arg0:
None
1. (
arg0: numpy.ndarray[float32[1, 3], flags.writeable]) ->
None
Invoked with: array([ 5., 4., 3.], dtype=float32)
Invoked with: array([ 5., 4., 3.], dtype=float32)
"""
"""
...
@@ -195,7 +195,7 @@ def test_negative_stride_from_python(msg):
...
@@ -195,7 +195,7 @@ def test_negative_stride_from_python(msg):
double_threec
(
second_col
)
double_threec
(
second_col
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
msg
(
excinfo
.
value
)
==
"""
double_threec(): incompatible function arguments. The following argument types are supported:
double_threec(): incompatible function arguments. The following argument types are supported:
1. (
numpy.ndarray[float32[3, 1], flags.writeable]) -> arg0:
None
1. (
arg0: numpy.ndarray[float32[3, 1], flags.writeable]) ->
None
Invoked with: array([ 7., 4., 1.], dtype=float32)
Invoked with: array([ 7., 4., 1.], dtype=float32)
"""
"""
...
...
tests/test_numpy_array.cpp
View file @
30d43c49
...
@@ -13,53 +13,52 @@
...
@@ -13,53 +13,52 @@
#include <pybind11/stl.h>
#include <pybind11/stl.h>
#include <cstdint>
#include <cstdint>
#include <vector>
using
arr
=
py
::
array
;
using
arr
=
py
::
array
;
using
arr_t
=
py
::
array_t
<
uint16_t
,
0
>
;
using
arr_t
=
py
::
array_t
<
uint16_t
,
0
>
;
static_assert
(
std
::
is_same
<
arr_t
::
value_type
,
uint16_t
>::
value
,
""
);
static_assert
(
std
::
is_same
<
arr_t
::
value_type
,
uint16_t
>::
value
,
""
);
template
<
typename
...
Ix
>
arr
data
(
const
arr
&
a
,
Ix
...
index
)
{
template
<
typename
...
Ix
>
arr
data
(
const
arr
&
a
,
Ix
...
index
)
{
return
arr
(
a
.
nbytes
()
-
size_t
(
a
.
offset_at
(
index
...)
),
(
const
uint8_t
*
)
a
.
data
(
index
...));
return
arr
(
a
.
nbytes
()
-
a
.
offset_at
(
index
...
),
(
const
uint8_t
*
)
a
.
data
(
index
...));
}
}
template
<
typename
...
Ix
>
arr
data_t
(
const
arr_t
&
a
,
Ix
...
index
)
{
template
<
typename
...
Ix
>
arr
data_t
(
const
arr_t
&
a
,
Ix
...
index
)
{
return
arr
(
a
.
size
()
-
size_t
(
a
.
index_at
(
index
...)
),
a
.
data
(
index
...));
return
arr
(
a
.
size
()
-
a
.
index_at
(
index
...
),
a
.
data
(
index
...));
}
}
arr
&
mutate_data
(
arr
&
a
)
{
arr
&
mutate_data
(
arr
&
a
)
{
auto
ptr
=
(
uint8_t
*
)
a
.
mutable_data
();
auto
ptr
=
(
uint8_t
*
)
a
.
mutable_data
();
for
(
size_t
i
=
0
;
i
<
a
.
nbytes
();
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
a
.
nbytes
();
i
++
)
ptr
[
i
]
=
(
uint8_t
)
(
ptr
[
i
]
*
2
);
ptr
[
i
]
=
(
uint8_t
)
(
ptr
[
i
]
*
2
);
return
a
;
return
a
;
}
}
arr_t
&
mutate_data_t
(
arr_t
&
a
)
{
arr_t
&
mutate_data_t
(
arr_t
&
a
)
{
auto
ptr
=
a
.
mutable_data
();
auto
ptr
=
a
.
mutable_data
();
for
(
size_t
i
=
0
;
i
<
a
.
size
();
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
a
.
size
();
i
++
)
ptr
[
i
]
++
;
ptr
[
i
]
++
;
return
a
;
return
a
;
}
}
template
<
typename
...
Ix
>
arr
&
mutate_data
(
arr
&
a
,
Ix
...
index
)
{
template
<
typename
...
Ix
>
arr
&
mutate_data
(
arr
&
a
,
Ix
...
index
)
{
auto
ptr
=
(
uint8_t
*
)
a
.
mutable_data
(
index
...);
auto
ptr
=
(
uint8_t
*
)
a
.
mutable_data
(
index
...);
for
(
s
ize_t
i
=
0
;
i
<
a
.
nbytes
()
-
size_t
(
a
.
offset_at
(
index
...)
);
i
++
)
for
(
s
size_t
i
=
0
;
i
<
a
.
nbytes
()
-
a
.
offset_at
(
index
...
);
i
++
)
ptr
[
i
]
=
(
uint8_t
)
(
ptr
[
i
]
*
2
);
ptr
[
i
]
=
(
uint8_t
)
(
ptr
[
i
]
*
2
);
return
a
;
return
a
;
}
}
template
<
typename
...
Ix
>
arr_t
&
mutate_data_t
(
arr_t
&
a
,
Ix
...
index
)
{
template
<
typename
...
Ix
>
arr_t
&
mutate_data_t
(
arr_t
&
a
,
Ix
...
index
)
{
auto
ptr
=
a
.
mutable_data
(
index
...);
auto
ptr
=
a
.
mutable_data
(
index
...);
for
(
s
ize_t
i
=
0
;
i
<
a
.
size
()
-
size_t
(
a
.
index_at
(
index
...)
);
i
++
)
for
(
s
size_t
i
=
0
;
i
<
a
.
size
()
-
a
.
index_at
(
index
...
);
i
++
)
ptr
[
i
]
++
;
ptr
[
i
]
++
;
return
a
;
return
a
;
}
}
template
<
typename
...
Ix
>
py
::
ssize_t
index_at
(
const
arr
&
a
,
Ix
...
idx
)
{
return
a
.
index_at
(
idx
...);
}
template
<
typename
...
Ix
>
ssize_t
index_at
(
const
arr
&
a
,
Ix
...
idx
)
{
return
a
.
index_at
(
idx
...);
}
template
<
typename
...
Ix
>
py
::
ssize_t
index_at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
index_at
(
idx
...);
}
template
<
typename
...
Ix
>
ssize_t
index_at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
index_at
(
idx
...);
}
template
<
typename
...
Ix
>
py
::
ssize_t
offset_at
(
const
arr
&
a
,
Ix
...
idx
)
{
return
a
.
offset_at
(
idx
...);
}
template
<
typename
...
Ix
>
ssize_t
offset_at
(
const
arr
&
a
,
Ix
...
idx
)
{
return
a
.
offset_at
(
idx
...);
}
template
<
typename
...
Ix
>
py
::
ssize_t
offset_at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
offset_at
(
idx
...);
}
template
<
typename
...
Ix
>
ssize_t
offset_at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
offset_at
(
idx
...);
}
template
<
typename
...
Ix
>
py
::
ssize_t
at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
at
(
idx
...);
}
template
<
typename
...
Ix
>
ssize_t
at_t
(
const
arr_t
&
a
,
Ix
...
idx
)
{
return
a
.
at
(
idx
...);
}
template
<
typename
...
Ix
>
arr_t
&
mutate_at_t
(
arr_t
&
a
,
Ix
...
idx
)
{
a
.
mutable_at
(
idx
...)
++
;
return
a
;
}
template
<
typename
...
Ix
>
arr_t
&
mutate_at_t
(
arr_t
&
a
,
Ix
...
idx
)
{
a
.
mutable_at
(
idx
...)
++
;
return
a
;
}
#define def_index_fn(name, type) \
#define def_index_fn(name, type) \
...
@@ -88,9 +87,9 @@ test_initializer numpy_array([](py::module &m) {
...
@@ -88,9 +87,9 @@ test_initializer numpy_array([](py::module &m) {
sm
.
def
(
"ndim"
,
[](
const
arr
&
a
)
{
return
a
.
ndim
();
});
sm
.
def
(
"ndim"
,
[](
const
arr
&
a
)
{
return
a
.
ndim
();
});
sm
.
def
(
"shape"
,
[](
const
arr
&
a
)
{
return
arr
(
a
.
ndim
(),
a
.
shape
());
});
sm
.
def
(
"shape"
,
[](
const
arr
&
a
)
{
return
arr
(
a
.
ndim
(),
a
.
shape
());
});
sm
.
def
(
"shape"
,
[](
const
arr
&
a
,
size_t
dim
)
{
return
a
.
shape
(
dim
);
});
sm
.
def
(
"shape"
,
[](
const
arr
&
a
,
s
s
ize_t
dim
)
{
return
a
.
shape
(
dim
);
});
sm
.
def
(
"strides"
,
[](
const
arr
&
a
)
{
return
arr
(
a
.
ndim
(),
a
.
strides
());
});
sm
.
def
(
"strides"
,
[](
const
arr
&
a
)
{
return
arr
(
a
.
ndim
(),
a
.
strides
());
});
sm
.
def
(
"strides"
,
[](
const
arr
&
a
,
size_t
dim
)
{
return
a
.
strides
(
dim
);
});
sm
.
def
(
"strides"
,
[](
const
arr
&
a
,
s
s
ize_t
dim
)
{
return
a
.
strides
(
dim
);
});
sm
.
def
(
"writeable"
,
[](
const
arr
&
a
)
{
return
a
.
writeable
();
});
sm
.
def
(
"writeable"
,
[](
const
arr
&
a
)
{
return
a
.
writeable
();
});
sm
.
def
(
"size"
,
[](
const
arr
&
a
)
{
return
a
.
size
();
});
sm
.
def
(
"size"
,
[](
const
arr
&
a
)
{
return
a
.
size
();
});
sm
.
def
(
"itemsize"
,
[](
const
arr
&
a
)
{
return
a
.
itemsize
();
});
sm
.
def
(
"itemsize"
,
[](
const
arr
&
a
)
{
return
a
.
itemsize
();
});
...
@@ -202,33 +201,33 @@ test_initializer numpy_array([](py::module &m) {
...
@@ -202,33 +201,33 @@ test_initializer numpy_array([](py::module &m) {
sm
.
def
(
"proxy_add2"
,
[](
py
::
array_t
<
double
>
a
,
double
v
)
{
sm
.
def
(
"proxy_add2"
,
[](
py
::
array_t
<
double
>
a
,
double
v
)
{
auto
r
=
a
.
mutable_unchecked
<
2
>
();
auto
r
=
a
.
mutable_unchecked
<
2
>
();
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
size_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
s
s
ize_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
r
(
i
,
j
)
+=
v
;
r
(
i
,
j
)
+=
v
;
},
py
::
arg
().
noconvert
(),
py
::
arg
());
},
py
::
arg
().
noconvert
(),
py
::
arg
());
sm
.
def
(
"proxy_init3"
,
[](
double
start
)
{
sm
.
def
(
"proxy_init3"
,
[](
double
start
)
{
py
::
array_t
<
double
,
py
::
array
::
c_style
>
a
({
3
,
3
,
3
});
py
::
array_t
<
double
,
py
::
array
::
c_style
>
a
({
3
,
3
,
3
});
auto
r
=
a
.
mutable_unchecked
<
3
>
();
auto
r
=
a
.
mutable_unchecked
<
3
>
();
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
size_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
s
s
ize_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
size_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
for
(
s
s
ize_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
r
(
i
,
j
,
k
)
=
start
++
;
r
(
i
,
j
,
k
)
=
start
++
;
return
a
;
return
a
;
});
});
sm
.
def
(
"proxy_init3F"
,
[](
double
start
)
{
sm
.
def
(
"proxy_init3F"
,
[](
double
start
)
{
py
::
array_t
<
double
,
py
::
array
::
f_style
>
a
({
3
,
3
,
3
});
py
::
array_t
<
double
,
py
::
array
::
f_style
>
a
({
3
,
3
,
3
});
auto
r
=
a
.
mutable_unchecked
<
3
>
();
auto
r
=
a
.
mutable_unchecked
<
3
>
();
for
(
size_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
for
(
s
s
ize_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
for
(
size_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
s
s
ize_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
r
(
i
,
j
,
k
)
=
start
++
;
r
(
i
,
j
,
k
)
=
start
++
;
return
a
;
return
a
;
});
});
sm
.
def
(
"proxy_squared_L2_norm"
,
[](
py
::
array_t
<
double
>
a
)
{
sm
.
def
(
"proxy_squared_L2_norm"
,
[](
py
::
array_t
<
double
>
a
)
{
auto
r
=
a
.
unchecked
<
1
>
();
auto
r
=
a
.
unchecked
<
1
>
();
double
sumsq
=
0
;
double
sumsq
=
0
;
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
sumsq
+=
r
[
i
]
*
r
(
i
);
// Either notation works for a 1D array
sumsq
+=
r
[
i
]
*
r
(
i
);
// Either notation works for a 1D array
return
sumsq
;
return
sumsq
;
});
});
...
@@ -243,17 +242,17 @@ test_initializer numpy_array([](py::module &m) {
...
@@ -243,17 +242,17 @@ test_initializer numpy_array([](py::module &m) {
sm
.
def
(
"proxy_add2_dyn"
,
[](
py
::
array_t
<
double
>
a
,
double
v
)
{
sm
.
def
(
"proxy_add2_dyn"
,
[](
py
::
array_t
<
double
>
a
,
double
v
)
{
auto
r
=
a
.
mutable_unchecked
();
auto
r
=
a
.
mutable_unchecked
();
if
(
r
.
ndim
()
!=
2
)
throw
std
::
domain_error
(
"error: ndim != 2"
);
if
(
r
.
ndim
()
!=
2
)
throw
std
::
domain_error
(
"error: ndim != 2"
);
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
size_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
s
s
ize_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
r
(
i
,
j
)
+=
v
;
r
(
i
,
j
)
+=
v
;
},
py
::
arg
().
noconvert
(),
py
::
arg
());
},
py
::
arg
().
noconvert
(),
py
::
arg
());
sm
.
def
(
"proxy_init3_dyn"
,
[](
double
start
)
{
sm
.
def
(
"proxy_init3_dyn"
,
[](
double
start
)
{
py
::
array_t
<
double
,
py
::
array
::
c_style
>
a
({
3
,
3
,
3
});
py
::
array_t
<
double
,
py
::
array
::
c_style
>
a
({
3
,
3
,
3
});
auto
r
=
a
.
mutable_unchecked
();
auto
r
=
a
.
mutable_unchecked
();
if
(
r
.
ndim
()
!=
3
)
throw
std
::
domain_error
(
"error: ndim != 3"
);
if
(
r
.
ndim
()
!=
3
)
throw
std
::
domain_error
(
"error: ndim != 3"
);
for
(
size_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
r
.
shape
(
0
);
i
++
)
for
(
size_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
s
s
ize_t
j
=
0
;
j
<
r
.
shape
(
1
);
j
++
)
for
(
size_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
for
(
s
s
ize_t
k
=
0
;
k
<
r
.
shape
(
2
);
k
++
)
r
(
i
,
j
,
k
)
=
start
++
;
r
(
i
,
j
,
k
)
=
start
++
;
return
a
;
return
a
;
});
});
...
@@ -269,6 +268,9 @@ test_initializer numpy_array([](py::module &m) {
...
@@ -269,6 +268,9 @@ test_initializer numpy_array([](py::module &m) {
sm
.
def
(
"array_fail_test"
,
[]()
{
return
py
::
array
(
py
::
object
());
});
sm
.
def
(
"array_fail_test"
,
[]()
{
return
py
::
array
(
py
::
object
());
});
sm
.
def
(
"array_t_fail_test"
,
[]()
{
return
py
::
array_t
<
double
>
(
py
::
object
());
});
sm
.
def
(
"array_t_fail_test"
,
[]()
{
return
py
::
array_t
<
double
>
(
py
::
object
());
});
// Make sure the error from numpy is being passed through:
sm
.
def
(
"array_fail_test_negative_size"
,
[]()
{
int
c
=
0
;
return
py
::
array
(
-
1
,
&
c
);
});
// Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous
// Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
(
1
);
});
// { 1 } also works, but clang warns about it
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
(
1
);
});
// { 1 } also works, but clang warns about it
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
({
1
,
2
});
});
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
({
1
,
2
});
});
...
@@ -277,7 +279,7 @@ test_initializer numpy_array([](py::module &m) {
...
@@ -277,7 +279,7 @@ test_initializer numpy_array([](py::module &m) {
// reshape array to 2D without changing size
// reshape array to 2D without changing size
sm
.
def
(
"array_reshape2"
,
[](
py
::
array_t
<
double
>
a
)
{
sm
.
def
(
"array_reshape2"
,
[](
py
::
array_t
<
double
>
a
)
{
const
s
ize_t
dim_sz
=
(
size_t
)
std
::
sqrt
(
a
.
size
());
const
s
size_t
dim_sz
=
(
s
size_t
)
std
::
sqrt
(
a
.
size
());
if
(
dim_sz
*
dim_sz
!=
a
.
size
())
if
(
dim_sz
*
dim_sz
!=
a
.
size
())
throw
std
::
domain_error
(
"array_reshape2: input array total size is not a squared integer"
);
throw
std
::
domain_error
(
"array_reshape2: input array total size is not a squared integer"
);
a
.
resize
({
dim_sz
,
dim_sz
});
a
.
resize
({
dim_sz
,
dim_sz
});
...
...
tests/test_numpy_array.py
View file @
30d43c49
...
@@ -384,7 +384,8 @@ def test_array_unchecked_dyn_dims(msg):
...
@@ -384,7 +384,8 @@ def test_array_unchecked_dyn_dims(msg):
def
test_array_failure
():
def
test_array_failure
():
from
pybind11_tests.array
import
array_fail_test
,
array_t_fail_test
from
pybind11_tests.array
import
(
array_fail_test
,
array_t_fail_test
,
array_fail_test_negative_size
)
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
array_fail_test
()
array_fail_test
()
...
@@ -394,6 +395,10 @@ def test_array_failure():
...
@@ -394,6 +395,10 @@ def test_array_failure():
array_t_fail_test
()
array_t_fail_test
()
assert
str
(
excinfo
.
value
)
==
'cannot create a pybind11::array_t from a nullptr'
assert
str
(
excinfo
.
value
)
==
'cannot create a pybind11::array_t from a nullptr'
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
array_fail_test_negative_size
()
assert
str
(
excinfo
.
value
)
==
'negative dimensions are not allowed'
def
test_array_resize
(
msg
):
def
test_array_resize
(
msg
):
from
pybind11_tests.array
import
(
array_reshape2
,
array_resize3
)
from
pybind11_tests.array
import
(
array_reshape2
,
array_resize3
)
...
...
tests/test_numpy_dtypes.cpp
View file @
30d43c49
...
@@ -149,7 +149,7 @@ py::array_t<StringStruct, 0> create_string_array(bool non_empty) {
...
@@ -149,7 +149,7 @@ py::array_t<StringStruct, 0> create_string_array(bool non_empty) {
if
(
non_empty
)
{
if
(
non_empty
)
{
auto
req
=
arr
.
request
();
auto
req
=
arr
.
request
();
auto
ptr
=
static_cast
<
StringStruct
*>
(
req
.
ptr
);
auto
ptr
=
static_cast
<
StringStruct
*>
(
req
.
ptr
);
for
(
size_t
i
=
0
;
i
<
req
.
size
*
req
.
itemsize
;
i
++
)
for
(
s
s
ize_t
i
=
0
;
i
<
req
.
size
*
req
.
itemsize
;
i
++
)
static_cast
<
char
*>
(
req
.
ptr
)[
i
]
=
0
;
static_cast
<
char
*>
(
req
.
ptr
)[
i
]
=
0
;
ptr
[
1
].
a
[
0
]
=
'a'
;
ptr
[
1
].
b
[
0
]
=
'a'
;
ptr
[
1
].
a
[
0
]
=
'a'
;
ptr
[
1
].
b
[
0
]
=
'a'
;
ptr
[
2
].
a
[
0
]
=
'a'
;
ptr
[
2
].
b
[
0
]
=
'a'
;
ptr
[
2
].
a
[
0
]
=
'a'
;
ptr
[
2
].
b
[
0
]
=
'a'
;
...
@@ -178,7 +178,7 @@ py::list print_recarray(py::array_t<S, 0> arr) {
...
@@ -178,7 +178,7 @@ py::list print_recarray(py::array_t<S, 0> arr) {
const
auto
req
=
arr
.
request
();
const
auto
req
=
arr
.
request
();
const
auto
ptr
=
static_cast
<
S
*>
(
req
.
ptr
);
const
auto
ptr
=
static_cast
<
S
*>
(
req
.
ptr
);
auto
l
=
py
::
list
();
auto
l
=
py
::
list
();
for
(
size_t
i
=
0
;
i
<
req
.
size
;
i
++
)
{
for
(
s
s
ize_t
i
=
0
;
i
<
req
.
size
;
i
++
)
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
ss
<<
ptr
[
i
];
ss
<<
ptr
[
i
];
l
.
append
(
py
::
str
(
ss
.
str
()));
l
.
append
(
py
::
str
(
ss
.
str
()));
...
@@ -225,7 +225,7 @@ py::array_t<int32_t, 0> test_array_ctors(int i) {
...
@@ -225,7 +225,7 @@ py::array_t<int32_t, 0> test_array_ctors(int i) {
using
arr_t
=
py
::
array_t
<
int32_t
,
0
>
;
using
arr_t
=
py
::
array_t
<
int32_t
,
0
>
;
std
::
vector
<
int32_t
>
data
{
1
,
2
,
3
,
4
,
5
,
6
};
std
::
vector
<
int32_t
>
data
{
1
,
2
,
3
,
4
,
5
,
6
};
std
::
vector
<
size_t
>
shape
{
3
,
2
};
std
::
vector
<
s
s
ize_t
>
shape
{
3
,
2
};
std
::
vector
<
ssize_t
>
strides
{
8
,
4
};
std
::
vector
<
ssize_t
>
strides
{
8
,
4
};
auto
ptr
=
data
.
data
();
auto
ptr
=
data
.
data
();
...
...
tests/test_numpy_vectorize.cpp
View file @
30d43c49
...
@@ -50,8 +50,8 @@ test_initializer numpy_vectorize([](py::module &m) {
...
@@ -50,8 +50,8 @@ test_initializer numpy_vectorize([](py::module &m) {
py
::
array_t
<
float
,
py
::
array
::
forcecast
>
arg2
,
py
::
array_t
<
float
,
py
::
array
::
forcecast
>
arg2
,
py
::
array_t
<
double
,
py
::
array
::
forcecast
>
arg3
py
::
array_t
<
double
,
py
::
array
::
forcecast
>
arg3
)
{
)
{
size_t
ndim
;
s
s
ize_t
ndim
;
std
::
vector
<
size_t
>
shape
;
std
::
vector
<
s
s
ize_t
>
shape
;
std
::
array
<
py
::
buffer_info
,
3
>
buffers
{{
arg1
.
request
(),
arg2
.
request
(),
arg3
.
request
()
}};
std
::
array
<
py
::
buffer_info
,
3
>
buffers
{{
arg1
.
request
(),
arg2
.
request
(),
arg3
.
request
()
}};
return
py
::
detail
::
broadcast
(
buffers
,
ndim
,
shape
);
return
py
::
detail
::
broadcast
(
buffers
,
ndim
,
shape
);
});
});
...
...
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