microgemm-0.1.0 has been yanked.
microgemm
General matrix multiplication with custom configuration in Rust.
The implementation is based on the BLIS microkernel approach.
Usage
The Kernel trait is the main abstraction of microgemm.
You can implement it yourself or use kernels that are already provided out of the box.
Implemented Kernels
| Name |
Scalar Types |
Target |
| GenericNxNKernel (N: 2, 4, 8, 16, 32) |
T: Copy + Zero + One + Mul + Add |
Any |
| NeonKernel |
f32 |
AArch64 and target feature neon |
| WasmSimd128Kernel |
f32 |
wasm32 and target feature simd128 |
gemm
use microgemm as mg;
use microgemm::Kernel as _;
fn main() {
let kernel = mg::kernels::Generic8x8Kernel::<f32>::new();
assert_eq!(kernel.mr(), 8);
assert_eq!(kernel.nr(), 8);
let pack_sizes = mg::PackSizes {
mc: 5 * kernel.mr(), kc: 190,
nc: 10 * kernel.nr(), };
let mut packing_buf = vec![0.0; pack_sizes.buf_len()];
let alpha = 2.0;
let beta = -3.0;
let (m, k, n) = (100, 380, 250);
let a = vec![2.0; m * k];
let b = vec![3.0; k * n];
let mut c = vec![4.0; m * n];
let a = mg::MatRef::new(m, k, &a, mg::Layout::RowMajor);
let b = mg::MatRef::new(k, n, &b, mg::Layout::RowMajor);
let mut c = mg::MatMut::new(m, n, &mut c, mg::Layout::RowMajor);
kernel.gemm(alpha, &a, &b, beta, &mut c, &pack_sizes, &mut packing_buf);
println!("{:?}", c.as_slice());
}
Also see no_alloc example for use without Vec.
Custom Kernel Implementation
use microgemm::{typenum::U4, Kernel, MatMut, MatRef};
struct CustomKernel;
impl Kernel for CustomKernel {
type Scalar = f64;
type Mr = U4;
type Nr = U4;
fn microkernel(
&self,
alpha: f64,
lhs: &MatRef<f64>,
rhs: &MatRef<f64>,
beta: f64,
dst: &mut MatMut<f64>,
) {
assert_eq!(lhs.row_stride(), 1);
assert_eq!(lhs.nrows(), Self::MR);
assert_eq!(rhs.col_stride(), 1);
assert_eq!(rhs.ncols(), Self::NR);
assert_eq!(dst.row_stride(), 1);
assert_eq!(dst.nrows(), Self::MR);
assert_eq!(dst.ncols(), Self::NR);
}
}
License
Licensed under either of Apache License, Version 2.0
or MIT license at your option.