Replies: 2 comments
-
I don't use the Eigen binding code myself. Let me add @WKarel who has contributed major portions of it (in particular, the bits that I think you are referring to). |
Beta Was this translation helpful? Give feedback.
0 replies
-
By the way, ndarray_import makes a copy when converting a np.ndarray for which only the C- or F-order does not match, which could be avoided by using np.asarray instead of np.ndarray.astype (which always copies). |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I've been looking into nanobind's
<nanobind/eigen/dense.h>
type casters recently, and noticed a couple of surprising behaviors. They aren't quite bugs, but they seem like they might be valuable to improve upon.One: The caster for Eigen plain types (
Matrix
, etc) requires that the input array be able to be converted into the memory layout that Eigen expects. However, this is generally Fortran-contiguous, and the non-numpy array types that nanobind supports (jax, tensorflow, pytorch) AFAICT provide no way to produce a Fortran-contiguous array. (You might be able to get pytorch to do it with an appropriate transposition, but eg tensorflow doesn't have a concept of variable strides at all.) Thus, if you pass in one of those other frameworks' array objects, the cast to the Eigen type will fail. This seems like an unnecessary limitation given that we're making a copy anyway.Two: When casting to
Eigen::Ref<const T>
and a dtype conversion is required, in most cases two copies will be made: one to make an ndarray with the correct dtype (but any strides), and another in the constructor of Eigen::Ref to get the data to be laid out with the correct strides. Similarly to the previous point, it feels like if we're making a copy we should be able to make it with the correct layout.Both of these seem like consequences of the approach "cast to an appropriate ndarray, then wrap that", given that the conversion is always done using methods provided by the exporter of the original array data. I'm not sure the best way to resolve them. For plain types, nanobind could optionally support inputs with different shape than the output, copying element-by-element rather than doing a memcpy; for Refs, nanobind could use the non-DStrided Map type if the input can be put in that form; but I'm not sure if either of these solutions is ideal, or worth the complexity cost.
Beta Was this translation helpful? Give feedback.
All reactions