An odd SIGSEGV when going off the beaten path (Rust + Python + C++) #1038
497e0bdf29873
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying to use nanobind a bit off the beaten path. I have existing computational Rust codes, where I now want to incorporate some PDEs, which is easiest done in Fenics in Python. (I'm not doing that part, but a postdoc is doing it. If I had infinite amounts of time myself, I'd do everything in Rust.) However, I also need to do some things in C++ in Fenics, whose core is written in C++, as this will not be efficient enough to do in Python. Thus, I need to interface
Rust ↔ Python ↔ C++ ↔ Rust.
I'm using PyO3 for the first, and Fenics dictates nanobind for the second. The third is done partially by CXX.rs, but I need to do some additional work to pass the nanobound types from Python back to C++ via Rust. (The nanobound direct Python ↔ C++ interface may in the end be provided by Fenics only, not my code.)
I also don't want to deal with CMake: I have a Rust application that just incorporates some C++ and Python in it, so I'll stick to Cargo.
Sounds like trouble, right? But I only really need one or two custom C++ functions that operate on a
Function<double_t>
of Fenics, provided by the Python component of the code, and return astd::span<double_t, 2>
. Ideally, I call my C++ function directly from Rust, without passing through Python. So I need to convert the nanobound C++ types, also wrapped in Rust by PyO3, back to C++. In the end that's not very complicated… until I get a SIGSEGV, but not because I'm doing something wrong here, I think.What's more complicated is all the compiling and initialisations without CMake. It's not ideal that I have to compile nanobind, but that's I guess how it is. I also figured out that I need
and then
to register the nanobind-generated module using PyO3. One would think that this would be enough for it to work. No!
If I don't also import the Python module, after I have the GIL (
Python::with_gil
from PyO3), with, e.g.,from Rust, or the obvious code in Python, then
nanobind::type<Function<double_t>>()
crashes with a SIGSEGV. This is in the type PyO3 → nanobind conversion type check
nanobind::isinstance<Function<double_t>>(handle)
.Why is this!??! Why does the module need to be imported (and not just registered) in Python, for the C++ code to work?
And
Function<double_t>
is not even my type, it's a type from Fenics. (I do need atypedef Function<double_t> Function_f64;
in my C++ namespace for CXX to work; it doesn't yet support general templates.) I shouldn't currently even really need a nanobind Python module for my own code (just Fenics itself), as I'm not currently accessing it from Python, if ever; I just created one to play around.Beta Was this translation helpful? Give feedback.
All reactions