Description
Hi,
I am building a Rust dynamic library embedding Python using rust-numpy. My project allows me to build a pure Rust binary, a C binary loading the Rust library and a Dotnet binary loading the Rust library. All three scenarios works on Windows but fails on Linux with "Error importing numpy".
The following code built as a cdylib is enough to reproduce the problem when imported into a Dotnet SDK 6.0 or 7.0 program
use numpy::{pyo3::{Python, self}, PyArray};
#[no_mangle]
pub extern "C" fn hello_world() {
// Demonstrates the DLL alone is compatible with Dotnet AnyCPU
println!("Hello, world!");
// Demonstrates the ORT DLL is compatible with Dotnet AnyCPU
println!("Using ort::LoggingLevel::Info : {:?}", ort::LoggingLevel::Info);
// Demonstrates the Numpy crate is compatible with Dotnet (only uses ndarray though)
println!("Using numpy::array![1, 2] {:?}", numpy::array![1, 2]);
// Demonstrates the Numpy crate using actual Python code (numpy array) => fails
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let slice = &[1, 2, 3, 4, 5];
let pyarray = PyArray::from_slice(py, slice);
println!("Using numpy::array::Pyarray {:?}", pyarray);
});
}
On Windows, the code succeeds
PS C:\Users\****\workspace\demo-rs> .\dotnet\demo_dotnet\bin\Debug\net6.0\demo_dotnet.exe
Starting C# code
Hello, world!
Using ort::LoggingLevel::Info : Info
Using numpy::array![1, 2] [1, 2], shape=[2], strides=[1], layout=CFcf (0xf), const ndim=1
Using nump::array::Pyarray array([1, 2, 3, 4, 5])
On Ubuntu, the code fails
****:~/workspace/demo-rs/dotnet/demo_dotnet/bin/Debug/net7.0$ LD_LIBRARY_PATH=. ./demo_dotnet
Starting C# code
Hello, world!
Using ort::LoggingLevel::Info : Info
Using numpy::array![1, 2] [1, 2], shape=[2], strides=[1], layout=CFcf (0xf), const ndim=1
thread '<unnamed>' panicked at 'Failed to access NumPy array API capsule: PyErr { type: <class 'ImportError'>, value: ImportError('Error importing numpy: you should not try to import numpy from\n its source directory; please exit the numpy source tree, and relaunch\n your python interpreter from there.'), traceback: Some(<traceback object at 0x7f47853a5900>) }', /home/****/.cargo/registry/src/index.crates.io-6f17d22bba15001f/numpy-0.20.0/src/npyffi/array.rs:52:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5
Aborted
The error triggers on import of numpy whether we use Rust PyArray or do a import numpy in Python. Removing references to numpy allows to execute Python code with success. For instance, I can print some informations from within Dotnet > Rust > Python as follows :
- sys.path -> ['/usr/lib/python311.zip', '/usr/lib/python3.11', '/usr/lib/python3.11/lib-dynload', '/home/****/.local/lib/python3.11/site-packages', '/usr/local/lib/python3.11/dist-packages', '/usr/lib/python3/dist-packages']
- os.getcwn() -> /home/****/workspace/test_project
Numpy was installed using pip3, but I don't think it has anything to do with my Python setup since the dynamic library works when tested from a C code. It seems the error message may be giving a false indication as to the real cause of the error.
Any help would be greatly appreciated!