-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Matrix conversion and variant issue #916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The core issue here is that pybind's variant caster doesn't keep the subcaster alive: it creates subcasters on the fly until one succeeds, at which point it copies out the This breaks the eigen caster for types like When a conversion is needed, on the other hand—as in your test case, with either incompatible strides or an incompatible type ( I pushed a fix to https://github.com/jagerman/pybind11/tree/variant-hold-subcaster that fixes it for variant (it's a pretty elegant fix, I think: reusing the variant template type itself to make a subcaster variant) but I haven't pushed it as a PR yet because the same issue is present in A nicer alternative is to allow type casters to export a The caster overhaul proposed in #864 suggests a nicer way of doing this: |
This is great, thank you for the quick fix and the detailed discussion of the issue! The concept described in the caster overhaul sounds sensible and like a good solution on the longer run. How would
Maybe two versions of |
I read through the comments of #924 and am not sure which one of the ways for handling |
Special effort is only taken to keep the converted object alive. The original stays alive on its own because it's owned by the caller. The original object comes into the function as a borrowed reference and we're not allowed to shorten its lifetime. On the other hand, Its lifetime could be extended if the converted object depends on it, but that usually happens automatically within Python so we don't need to worry about it (that is, we don't need a special life support system like for the converted object). |
The keep-alive in question is entirely internal to the pybind implementation. Essentially what we do is created an internal python list and, if a temporary The list itself is cleared when the function call ends, at which point destruction of the temporary is allowed to occur. So essentially, when you call a bound function with a conforming type (i.e. matching dtype and compatible strides), the def f_wrap(m):
x = np.array(m, dtype='double', order='F')
f(x)
f_wrap(myarray) where the temporary |
Ok, great! Thanks for the quick answers and the good solution! |
Hi!
I came across the following issue working with variants of Eigen matrices (which is an amazing feature, by the way):
Issue description
When calling the function, parameterized with a variant over Eigen const matrix references with an Eigen matrix over a certain size that needs to be converted, I get a segmentation fault. This works flawlessly with smaller matrices. I do not suspect the variant implementation is the problem, because if I shift the conversion out of pybind11 and do it myself in a c++ function, it works flawlessly, also it works if the matrix doesn't have to be converted.
Reproducible example code
example.py:
CMakeLists.txt:
example.cpp
This assumes that
pybind11-master
,eigen3-v3.3
andvariant-v1.1.4
are subfolders, variant can be downloaded from here, but probablystd::variant
can be used in the same way. If.noconvert()
is used, the function works just as expected, which I use as a workaround.Another probably only slightly related issue I came across in this setting is the
keep_alive
policy, which also doesn't work for these kind of converted arguments (I assume the original object that is passed to the variant is kept alive, but the converted object that the Eigen::Ref points to in the end is not). I'm not 100% sure on this one, though, and may open a dedicated issue once I have a proper test case.The text was updated successfully, but these errors were encountered: