Crate mdarray[−][src]
Expand description
Multidimensional array for Rust
Overview
The mdarray crate provides a multidimensional array for Rust. Its main target is for numeric types, however generic types are supported as well. The purpose is to provide a generic container type that is simple and flexible to use, with interworking to other crates for e.g. BLAS/LAPACK functionality.
Here are the main features of mdarray:
- Dense array type, where the rank and element order is known at compile time.
- Column-major and row-major element order.
- Subarrays (views) can be created with arbitrary shapes and strides.
- Standard Rust mechanisms are used for e.g. slices, indexing and iteration.
The design is inspired from the Rust ndarray, nalgebra and bitvec crates, the proposed C++ mdarray and mdspan types, and multidimensional arrays in Julia and Matlab.
Note that this crate requires nightly Rust toolchain.
Array types
The base types for multidimensional arrays are GridBase
and SpanBase
,
similar to the Rust Vec
and slice
types.
GridBase
consists of a buffer for element storage and information about
the array layout. The buffer can either own the storage like Vec
, or refer
to a parent array. The latter case occurs for example when creating a view
of a larger array without duplicating elements.
SpanBase
is used as a generic array reference. It consists of pointers
to the buffer and the layout, and is stored internally as a fat pointer.
It is useful for function parameters where the same SpanBase
type can
refer to either an owned array or an array view.
The array layout describes how elements are accessed in memory. The layout is parameterized by the rank (i.e. the number of dimensions), the storage format and the element order. It contains the shape (i.e. the size in each dimension), and the strides per dimension if needed.
The storage format is Dense
if elements are stored contiguously without gaps.
In this case, the strides are calculated from the shape and not stored as
part of the layout. The format is General
if each dimension can have an
arbitrary stride, except for the innermost one which must have unit stride.
It is compatible with the BLAS/LAPACK general matrix storage. The format is
Strided
if the innermost dimension can also have arbitrary stride.
The element order is ColumnMajor
for Fortran order where the innermost
dimension is the innermost one, or RowMajor
for the opposite C order.
Besides indexing for element access, the order affects how iteration is done
over multiple dimensions.
The following type aliases are provided:
Alias | Description |
---|---|
Grid<T, const N: usize> | Dense array with column-major order |
CGrid<T, const N: usize> | Dense array with row-major order |
Span<T, const N: usize> | Dense array span with column-major order |
CSpan<T, const N: usize> | Dense array span with row-major order |
Indexing and views
Scalar indexing is done using the normal square-bracket index operator and
an array of usize
per dimension as index.
For one-dimensional arrays, indexing can also be done with a scalar usize
as index. If the storage format is Dense
or General
, a range can be
used as index to select a one-dimensional array span.
An array view can be created with the view
and view_mut
methods and a
tuple of indices per dimension as argument. Each index can be either a range
or usize
. The resulting storage format depends on both the format inferred
from the indices and the input format.
Iteration
For one-dimensional arrays, an iterator can be created with the iter
,
iter_mut
and into_iter
methods like Vec
and slice
.
For multidimensional arrays, indexing over a single dimension is done
with the outer_iter
/outer_iter_mut
, inner_iter
/inner_iter_mut
and
axis_iter
/axis_iter_mut
methods. The iterators give array views of
the remaining dimensions.
For multidimensional arrays with contiguous array layout, it is possible
to use the flat_iter
and flat_iter_mut
to iterate over all dimensions.
The methods will check at runtime and panic if the layout is not contiguous.
Example
The following example implements simple matrix multiplication C = A * B + C
.
The matrices use column-major ordering, and the inner loop runs over one column
in A
and C
. By using iterators the array bounds checking is avoided, and
the compiler is able to vectorize the inner loop.
use mdarray::{Grid, Span};
pub fn matmul(a: &Span<f64, 2>, b: &Span<f64, 2>, c: &mut Span<f64, 2>) {
assert!(c.shape() == [a.size(0), b.size(1)] && a.size(1) == b.size(0), "shape mismatch");
for (mut cj, bj) in c.outer_iter_mut().zip(b.outer_iter()) {
for (ak, bkj) in a.outer_iter().zip(bj.iter()) {
for (cij, aik) in cj.iter_mut().zip(ak.iter()) {
*cij += aik * bkj;
}
}
}
}
let a = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]].as_ref();
let b = [[0.0, 1.0], [1.0, 1.0]].as_ref();
let mut c = Grid::from([[0.0; 3]; 2]);
matmul(a, b, &mut c);
println!("{c:?}");
This will produce the result [[4.0, 5.0, 6.0], [5.0, 7.0, 9.0]]
.
Structs
Aligned memory allocator, using the global allocator as default.
Column-major order, for indexing and iteration over array elements.
Type-level constant.
Dense array format type.
Dense array layout type.
General array format type.
General array layout type.
Multidimensional array with static rank and element order.
Row-major order, for indexing and iteration over array elements.
Multidimensional array span with static rank and element order.
Strided array format type.
Strided array layout type.
Traits
Array dimension trait.
Array format trait.
Array layout, including rank, shape, strides and element order.
Order for indexing and iteration over array elements.
Array shape trait.
Array strides trait.
Type Definitions
Dense multidimensional array with row-major element order.
Dense multidimensional array span with row-major element order.
Dense multidimensional array with static rank and element order.
Dense multidimensional array with column-major element order.
Dense multidimensional array span with column-major element order.
Multidimensional array view with static rank and element order.
Mutable multidimensional array view with static rank and element order.