Merge pull request #335 from aldanor/bugfix/is_pod_struct

Decay types before passing to is_pod_struct<> / npy_format_descriptor<>
This commit is contained in:
Wenzel Jakob 2016-08-15 20:12:06 +02:00 committed by GitHub
commit 94f2052d08
2 changed files with 28 additions and 84 deletions

View File

@ -85,7 +85,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value &&
if (!buffer.check()) if (!buffer.check())
return false; return false;
buffer_info info = buffer.request(); auto info = buffer.request();
if (info.ndim == 1) { if (info.ndim == 1) {
typedef Eigen::InnerStride<> Strides; typedef Eigen::InnerStride<> Strides;
if (!isVector && if (!isVector &&
@ -127,37 +127,19 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value &&
static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
if (isVector) { if (isVector) {
return array(buffer_info( return array(
/* Pointer to buffer */ { (size_t) src.size() }, // shape
const_cast<Scalar *>(src.data()), { sizeof(Scalar) * static_cast<size_t>(src.innerStride()) }, // strides
/* Size of one scalar */ src.data() // data
sizeof(Scalar), ).release();
/* Python struct-style format descriptor */
format_descriptor<Scalar>::format(),
/* Number of dimensions */
1,
/* Buffer dimensions */
{ (size_t) src.size() },
/* Strides (in bytes) for each index */
{ sizeof(Scalar) * static_cast<size_t>(src.innerStride()) }
)).release();
} else { } else {
return array(buffer_info( return array(
/* Pointer to buffer */ { (size_t) src.rows(), // shape
const_cast<Scalar *>(src.data()),
/* Size of one scalar */
sizeof(Scalar),
/* Python struct-style format descriptor */
format_descriptor<Scalar>::format(),
/* Number of dimensions */
isVector ? 1 : 2,
/* Buffer dimensions */
{ (size_t) src.rows(),
(size_t) src.cols() }, (size_t) src.cols() },
/* Strides (in bytes) for each index */ { sizeof(Scalar) * static_cast<size_t>(src.rowStride()), // strides
{ sizeof(Scalar) * static_cast<size_t>(src.rowStride()), sizeof(Scalar) * static_cast<size_t>(src.colStride()) },
sizeof(Scalar) * static_cast<size_t>(src.colStride()) } src.data() // data
)).release(); ).release();
} }
} }
@ -248,9 +230,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
!outerIndicesArray.check()) !outerIndicesArray.check())
return false; return false;
buffer_info outerIndices = outerIndicesArray.request(); auto outerIndices = outerIndicesArray.request();
buffer_info innerIndices = innerIndicesArray.request(); auto innerIndices = innerIndicesArray.request();
buffer_info values = valuesArray.request(); auto values = valuesArray.request();
value = Eigen::MappedSparseMatrix<Scalar, Type::Flags, StorageIndex>( value = Eigen::MappedSparseMatrix<Scalar, Type::Flags, StorageIndex>(
shape[0].cast<Index>(), shape[0].cast<Index>(),
@ -270,50 +252,9 @@ struct type_caster<Type, typename std::enable_if<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(buffer_info( array data((size_t) src.nonZeros(), src.valuePtr());
// Pointer to buffer array outerIndices((size_t) (rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
const_cast<Scalar *>(src.valuePtr()), array innerIndices((size_t) src.nonZeros(), src.innerIndexPtr());
// Size of one scalar
sizeof(Scalar),
// Python struct-style format descriptor
format_descriptor<Scalar>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) src.nonZeros() },
// Strides
{ sizeof(Scalar) }
));
array outerIndices(buffer_info(
// Pointer to buffer
const_cast<StorageIndex *>(src.outerIndexPtr()),
// Size of one scalar
sizeof(StorageIndex),
// Python struct-style format descriptor
format_descriptor<StorageIndex>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) (rowMajor ? src.rows() : src.cols()) + 1 },
// Strides
{ sizeof(StorageIndex) }
));
array innerIndices(buffer_info(
// Pointer to buffer
const_cast<StorageIndex *>(src.innerIndexPtr()),
// Size of one scalar
sizeof(StorageIndex),
// Python struct-style format descriptor
format_descriptor<StorageIndex>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) src.nonZeros() },
// Strides
{ sizeof(StorageIndex) }
));
return matrix_type( return matrix_type(
std::make_tuple(data, innerIndices, outerIndices), std::make_tuple(data, innerIndices, outerIndices),

View File

@ -146,7 +146,7 @@ public:
} }
template <typename T> static dtype of() { template <typename T> static dtype of() {
return detail::npy_format_descriptor<T>::dtype(); return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();
} }
size_t itemsize() const { size_t itemsize() const {
@ -304,7 +304,9 @@ public:
template <typename T> template <typename T>
struct format_descriptor<T, typename std::enable_if<detail::is_pod_struct<T>::value>::type> { struct format_descriptor<T, typename std::enable_if<detail::is_pod_struct<T>::value>::type> {
static std::string format() { return detail::npy_format_descriptor<T>::format(); } static std::string format() {
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::format();
}
}; };
template <size_t N> struct format_descriptor<char[N]> { template <size_t N> struct format_descriptor<char[N]> {
@ -321,14 +323,15 @@ template <typename T, size_t N> struct is_std_array<std::array<T, N>> : std::tru
template <typename T> template <typename T>
struct is_pod_struct { struct is_pod_struct {
enum { value = std::is_pod<T>::value && // offsetof only works correctly for POD types enum { value = std::is_pod<T>::value && // offsetof only works correctly for POD types
!std::is_reference<T>::value &&
!std::is_array<T>::value && !std::is_array<T>::value &&
!is_std_array<T>::value && !is_std_array<T>::value &&
!std::is_integral<T>::value && !std::is_integral<T>::value &&
!std::is_same<T, float>::value && !std::is_same<typename std::remove_cv<T>::type, float>::value &&
!std::is_same<T, double>::value && !std::is_same<typename std::remove_cv<T>::type, double>::value &&
!std::is_same<T, bool>::value && !std::is_same<typename std::remove_cv<T>::type, bool>::value &&
!std::is_same<T, std::complex<float>>::value && !std::is_same<typename std::remove_cv<T>::type, std::complex<float>>::value &&
!std::is_same<T, std::complex<double>>::value }; !std::is_same<typename std::remove_cv<T>::type, std::complex<double>>::value };
}; };
template <typename T> struct npy_format_descriptor<T, typename std::enable_if<std::is_integral<T>::value>::type> { template <typename T> struct npy_format_descriptor<T, typename std::enable_if<std::is_integral<T>::value>::type> {