Rust bindings for the NumPy C-API
- current nightly rust (see PyO3/pyo3#5 for nightly features, and https://github.com/PyO3/pyo3/blob/master/build.rs for minimum required version)
- some rust libraries
- ndarray for rust-side matrix library
- pyo3 for cpython binding
- and more (see Cargo.toml)
- numpy installed in your python environments (e.g., via
pip install numpy
)
Note Starting from 0.3, rust-numpy migrated from rust-cpython to pyo3. If you want to use rust-cpython, use version 0.2.1 from crates.io.
Currently 3.5, 3.6, 3.7 are supported.
Version 0.5.0 is the last version that supports Python2.
If you want to compile this library with Python2, please use 0.5.0 from crates.io.
In addition, you have to add a feature flag in Cargo.toml
like
[dependencies.numpy]
version = "0.5.0"
features = ["python2"]
.
You can also automatically specify python version in setup.py, using setuptools-rust.
[package]
name = "numpy-test"
[dependencies]
pyo3 = "0.6.0"
numpy = "0.5.0"
extern crate numpy;
extern crate pyo3;
use numpy::{PyArray1, get_array_module};
use pyo3::prelude::{ObjectProtocol, PyResult, Python};
use pyo3::types::PyDict;
fn main() -> Result<(), ()> {
let gil = Python::acquire_gil();
main_(gil.python()).map_err(|e| {
eprintln!("error! :{:?}", e);
// we can't display python error type via ::std::fmt::Display
// so print error here manually
e.print_and_set_sys_last_vars(gil.python());
})
}
fn main_<'py>(py: Python<'py>) -> PyResult<()> {
let np = py.import("numpy")?;
let dict = PyDict::new(py);
dict.set_item("np", np)?;
let pyarray: &PyArray1<i32> = py
.eval("np.absolute(np.array([-1, -2, -3], dtype='int32'))", Some(&dict), None)?
.extract()?;
let slice = pyarray.as_slice();
assert_eq!(slice, &[1, 2, 3]);
Ok(())
}
Please see the example directory for a complete example
[lib]
name = "rust_ext"
crate-type = ["cdylib"]
[dependencies]
numpy = "0.5.0"
ndarray = "0.12"
[dependencies.pyo3]
version = "0.6.0"
features = ["extension-module"]
extern crate ndarray;
extern crate numpy;
extern crate pyo3;
use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
use numpy::{IntoPyArray, PyArrayDyn};
use pyo3::prelude::{pymodule, Py, PyModule, PyResult, Python};
#[pymodule]
fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> {
// immutable example
fn axpy(a: f64, x: ArrayViewD<f64>, y: ArrayViewD<f64>) -> ArrayD<f64> {
a * &x + &y
}
// mutable example (no return)
fn mult(a: f64, mut x: ArrayViewMutD<f64>) {
x *= a;
}
// wrapper of `axpy`
#[pyfn(m, "axpy")]
fn axpy_py(
py: Python,
a: f64,
x: &PyArrayDyn<f64>,
y: &PyArrayDyn<f64>,
) -> Py<PyArrayDyn<f64>> {
let x = x.as_array();
let y = y.as_array();
axpy(a, x, y).into_pyarray(py).to_owned()
}
// wrapper of `mult`
#[pyfn(m, "mult")]
fn mult_py(_py: Python, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
let x = x.as_array_mut();
mult(a, x);
Ok(())
}
Ok(())
}
We need your feedback.
Don't hesitate to open issues!
-
v0.5.0
- Update PyO3 to 0.6
-
v0.4.0
- Duplicate
PyArrayModule
and import Numpy API automatically - Fix memory leak of
IntoPyArray
and addToPyArray
crate - PyArray has dimension as type parameter. Now it looks like
PyArray<T, D>
- Use
ndarray::IntoDimension
to specify dimension - Python2 support
- Duplicate
-
v0.3.1, v0.3.2
- Just update dependencies
-
v0.3.0
- Breaking Change: Migrated to pyo3 from rust-cpython
- Some api addition
- Static type checking with PhantomData
-
v0.2.1
- NEW: trait
IntoPyErr
,IntoPyResult
for error translation
- NEW: trait
-
v0.2.0
- NEW: traits
IntoPyArray
,ToPyArray
- MOD: Interface of
PyArray
creation functions are changed
- NEW: traits
-
v0.1.1
- Update documents
-
v0.1.0
- First Release
- Expose unsafe interface of Array and UFunc API