Expand description
Safe interface for NumPy’s random BitGenerator.
Using the patterns described in “Extending numpy.random”,
you can generate random numbers without being attached to the interpreter runtime by:
- spawning fresh
BitGenerators from aPyBitGeneratoryou received from Python - creating a fresh
BitGeneratorfrom numpy:
use pyo3::prelude::*;
use numpy::random::BitGenerator;
let mut bitgen = Python::attach(|py| {
BitGenerator::new(py, Default::default())
})?;
let random_number = bitgen.next_u64();If you write a pyo3 extension, you would extract
a numpy.random.BitGenerator into a [Bound]<’_, PyBitGenerator>:
use numpy::random::{BitGenerator, PyBitGenerator, PyBitGeneratorMethods as _};
#[pyfunction]
fn make_random_number(bitgen: Bound<PyBitGenerator>) -> PyResult<u64> {
// spawn an owned child, then use it without being attached to the interpreter runtime
Ok(bitgen.spawn_one()?.next_u64())
}
Python::attach(|py| -> PyResult<_> {
let bitgen: Bound<PyBitGenerator> = default_bit_gen(py)?;
let random_number = make_random_number(bitgen)?;
println!("{random_number}");
Ok(())
})?;With the rand crate installed, you can also use its Rng APIs on any generator,
since BitGenerator implements rand_core::RngCore.
use pyo3::prelude::*;
use rand::Rng as _;
use numpy::random::{BitGenerator, BitGeneratorKind::SFC64};
let mut bitgen = Python::attach(|py| BitGenerator::new(py, SFC64))?;
if bitgen.random_ratio(1, 1_000_000) {
println!("a sure thing");
};Using spawn, you can create multiple BitGenerators to generate random numbers truly in parallel,
all without being attached to the interpreter runtime:
use numpy::{PyArray2, PyArrayMethods as _};
Python::attach(|py| -> PyResult<_> {
let bitgen: Bound<PyBitGenerator> = default_bit_gen(py)?;
let children = bitgen.spawn(4)?;
let mut arr = PyArray2::<u32>::zeros(py, (4, 300), false).readwrite();
let mut ndarr = arr.as_array_mut(); // ndarray for more convenience
py.detach(|| std::thread::scope(|s| {
for (mut chunk, mut child) in ndarr.rows_mut().into_iter().zip(children) {
s.spawn(move || {
for x in chunk.iter_mut() {
*x = child.random_range(10..200);
}
});
}
}));
println!("Now filled: {arr:?}");
Ok(())
})?;Structs§
- BitGenerator
- A numpy
BitGeneratorusable without being attached to the interpreter runtime, with exclusive access to its state. - PyBit
Generator - Wrapper for
np.random.BitGenerator.
Enums§
- BitGenerator
Kind - Which of numpy’s bit generator algorithms
BitGenerator::newshould create.
Traits§
- PyBit
Generator Methods - Methods for
PyBitGenerator.