Skip to content

Commit

Permalink
Vector- Addition, Multiplication, Subtraction and Divition
Browse files Browse the repository at this point in the history
  • Loading branch information
unic0rn9k committed Apr 12, 2022
1 parent 301f834 commit f7f20d8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "slas"
version = "0.2.1"
version = "0.3.0"
edition = "2018"
authors = ["Aksel Mannstaedt <[email protected]>"]
license = "Apache-2.0"

repository = "https://github.com/unic0rn9k/slas"
description = "Static Linear Algebra System"

keywords = ["matrix", "blas", "linearalgebra", "matrix", "vectors"]
keywords = ["matrix", "blas", "linearalgebra", "vectors"]
categories = ["data-structures", "science", "mathematics"]

readme = "README.md"
Expand Down
32 changes: 24 additions & 8 deletions src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,30 @@ impl_operations!(T

Addition
add(const LEN: usize)()(
a: &mut impl StaticVec<T, LEN>,
b: &impl StaticVec<T, LEN>
a: &impl StaticVec<T, LEN>,
b: &impl StaticVec<T, LEN>,
c: &mut impl StaticVec<T, LEN>
) where () -> ();

Subtraction
sub(const LEN: usize)()(
a: &impl StaticVec<T, LEN>,
b: &impl StaticVec<T, LEN>,
c: &mut impl StaticVec<T, LEN>
) where () -> ();

Multiplication
mul(const LEN: usize)()(
a: &impl StaticVec<T, LEN>,
b: &impl StaticVec<T, LEN>,
c: &mut impl StaticVec<T, LEN>
) where () -> ();

Divition
div(const LEN: usize)()(
a: &impl StaticVec<T, LEN>,
b: &impl StaticVec<T, LEN>,
c: &mut impl StaticVec<T, LEN>
) where () -> ();
);

Expand Down Expand Up @@ -241,12 +263,6 @@ macro_rules! impl_default_ops {
Rust.dot(self, other)
}
}

/// Vector addidion.
pub fn add(mut self, other: &Self) -> Self {
Rust.add(&mut self, other);
self
}
}
};
}
Expand Down
59 changes: 45 additions & 14 deletions src/backends/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub struct Rust;
use super::*;
use operations::*;
use std::mem::transmute;
use std::simd::Simd;

macro_rules! impl_dot {
Expand Down Expand Up @@ -40,33 +41,60 @@ macro_rules! impl_dot {
};
}

macro_rules! impl_add {
($t: ty) => {
impl Addition<$t> for Rust {
fn add<const LEN: usize>(
macro_rules! impl_basic_op {
($op: ident, $fn: ident, $float_op: tt, $op_assign: ident, $($t: ty),*) => {$(
/// Basic element wise operators are implemented for all vectors on the rust backend.
/// This means you can call `a.add(&b)` to add two vectors together.
/// Whis ofcourse also works with `.sub`, `.mul` and `.div`.
impl $op<$t> for Rust {
fn $fn<const LEN: usize>(
&self,
a: &mut impl StaticVec<$t, LEN>,
a: &impl StaticVec<$t, LEN>,
b: &impl StaticVec<$t, LEN>,
c: &mut impl StaticVec<$t, LEN>,
) -> () {
const LANES: usize = crate::simd_lanes::max_for_type::<$t>();

let a = a.mut_moo_ref();
let out_ptr: *mut [$t; LANES] = unsafe{transmute(c.as_mut_ptr())};

for n in 0..LEN / LANES {
unsafe {
*std::mem::transmute::<_, *mut Simd<$t, LANES>>(a.as_mut_ptr())
.add(n * LANES) +=
Simd::from_slice(a.static_slice_unchecked::<LANES>(n * LANES))
+ Simd::from_slice(b.static_slice_unchecked::<LANES>(n * LANES))
*out_ptr.add(n) = transmute(
Simd::<$t, LANES>::from_slice(a.static_slice_unchecked::<LANES>(n * LANES)) $float_op
Simd::<$t, LANES>::from_slice(b.static_slice_unchecked::<LANES>(n * LANES)))
}
}

for n in LEN - (LEN % LANES)..LEN {
unsafe { *a.get_unchecked_mut(n) += b.get_unchecked(n) };
unsafe { *c.get_unchecked_mut(n) = *a.get_unchecked(n) $float_op *b.get_unchecked(n) };
}
}
}
};

impl<'a, const LEN: usize> StaticVecUnion<'a, $t, LEN> {
/// Basic vector operations, implemented automatically with macro.
#[inline(always)]
pub fn $fn(&self, other: &Self) -> Self{
unsafe{
let mut buffer: Self = std::mem::MaybeUninit::uninit().assume_init();
$op::$fn(&Rust, self, other, &mut buffer);
buffer
}
}
}

paste!{
#[test]
fn [< basic_ $fn _ $t >](){
let a = moo![$t: 1..13];
let b = a.$fn(&a);

for n in 0..12{
assert_eq!(a[n] $float_op a[n], b[n])
}
}
}
)*};
}

macro_rules! impl_norm {
Expand Down Expand Up @@ -139,8 +167,11 @@ impl_norm!(f64);

impl_dot!(f32);
impl_dot!(f64);
impl_add!(f32);
impl_add!(f64);

impl_basic_op!(Addition, add, +, add_assign, f32, f64);
impl_basic_op!(Multiplication, mul, *, mul_assign, f32, f64);
impl_basic_op!(Divition, div, /, div_assign, f32, f64);
impl_basic_op!(Subtraction, sub, -, sub_assign, f32, f64);

impl Backend<f32> for Rust {}
impl Backend<f64> for Rust {}
Expand Down
11 changes: 0 additions & 11 deletions tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,17 +232,6 @@ mod moo {
assert_eq!(a[0], *b[0]);
}
}

#[test]
fn add() {
use slas::prelude::*;

let mut a = moo![f32: 1, 2, 3];
let b = moo![f32: 1..4];

slas_backend::Rust.add(&mut a, &b);
assert_eq!(*a.add(&b), [3., 6., 9.,]);
}
}

#[cfg(test)]
Expand Down

0 comments on commit f7f20d8

Please sign in to comment.