Bug 632 - Create Vector Math library shared with Rust's project portable SIMD (`std::simd`)
Summary: Create Vector Math library shared with Rust's project portable SIMD (`std::si...
Status: IN_PROGRESS
Alias: None
Product: Libre-SOC's first SoC
Classification: Unclassified
Component: Source Code (show other bugs)
Version: unspecified
Hardware: Other Linux
: --- enhancement
Assignee: Jacob Lifshay
URL:
Depends on: 652
Blocks: 54
  Show dependency treegraph
 
Reported: 2021-04-26 00:28 BST by Jacob Lifshay
Modified: 2022-06-16 14:26 BST (History)
3 users (show)

See Also:
NLnet milestone: NLnet.2019.02.012
total budget (EUR) for completion of task and all subtasks: 1000
budget (EUR) for this task, excluding subtasks' budget: 0
parent task for budget allocation: 54
child tasks for budget allocation: 652
The table of payments (in EUR) for this task; TOML format:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jacob Lifshay 2021-04-26 00:28:41 BST
We're going to need a Vector Math library for the Kazan Vulkan driver in order to implement all the functions that Vulkan requires (basically all the sin, cos, tan, atan, sinpi, cospi, exp, log2, pow, etc. functions), if we work together on the same library we could also use it for Rust's `std::simd`, potentially saving a bit of work. Both Kazan and rustc share backends (LLVM and cranelift) and would like to support having vector math functions inlined into calling code, giving a potentially substantial performance boost.

Implementation at:
https://salsa.debian.org/Kazan-team/vector-math

Implemented functions so far:
`f16`/`f32`/`f64`:
* `abs`, `copy_sign`, `trunc`, `round_to_nearest_ties_to_even`, `floor`, `ceil`
* `ilogb`
* `sin_pi`, `cos_pi`, `sin_cos_pi`, `tan_pi`
* `sqrt_fast`

`u8`/`u16`/`u32`/`u64`/`i8`/`i16`/`i32`/`i64`:
* `count_leading_zeros`
* `count_trailing_zeros`
* `count_ones`

TODO:
*
*
Comment 1 Jacob Lifshay 2021-04-26 00:34:53 BST
Matching bug on Rust's std::simd bugtracker:
https://github.com/rust-lang/stdsimd/issues/109
Comment 2 Jacob Lifshay 2021-04-26 00:40:35 BST
provisionally assigning EUR 2000, to be adjusted as needed.
Comment 3 Luke Kenneth Casson Leighton 2021-04-26 13:20:07 BST
(In reply to Jacob Lifshay from comment #2)
> provisionally assigning EUR 2000, to be adjusted as needed.

be very careful about assigning funds: there is only around EUR 2500
left from the NLnet 2019 or it might actually be over-budget.
we *may* be able to receive some funds from NLnet if they have
spare, however it is not guaranteed.
Comment 4 Luke Kenneth Casson Leighton 2021-04-26 14:24:05 BST
very quick hack to get the total payments issued per top-level milestone
https://git.libre-soc.org/?p=utils.git;a=commitdiff;h=df61adb514d7e33819e3672eebf6fde279118d2c

Milestone(identifier='NLnet.2019.02', canonical_bug_id=191)

     27525


we're good.  it's a lot less than i thought.  at least 22,000 available.
Comment 5 Luke Kenneth Casson Leighton 2021-04-26 20:59:35 BST
ah.  just a reminder, jacob: we cannot deviate from the original
(agreed) Memorandum of Understanding.  we simply cannot arbitrarily
"add new tasks".

however, if during the course of implementing one such pre-agreed task,
a library happens to be needed which does not exist, then yes,
that's perfectly fine.
Comment 6 Jacob Lifshay 2021-04-26 21:20:17 BST
(In reply to Luke Kenneth Casson Leighton from comment #5)
> ah.  just a reminder, jacob: we cannot deviate from the original
> (agreed) Memorandum of Understanding.  we simply cannot arbitrarily
> "add new tasks".
> 
> however, if during the course of implementing one such pre-agreed task,
> a library happens to be needed which does not exist, then yes,
> that's perfectly fine.

Yup! We'd need this library because a SimpleV-capable math library doesn't exist, we need to build one. We can share the implementation costs with Rust's std::simd (which also wants a vector math library without libc, libm, or OS dependencies for use in Rust's `core` library). In particular, this means the math library will have generic vector-length-independent implementations written in Rust.
Comment 7 Jacob Lifshay 2021-05-01 03:49:26 BST
Started an implementation at https://salsa.debian.org/Kazan-team/vector-math
Comment 8 Jacob Lifshay 2021-05-03 12:21:35 BST
From https://github.com/rust-lang/stdsimd/issues/109#issuecomment-831196244
Got all the vector traits wired up for use with scalars (where all vectors are length 1 for testing purposes or otherwise) and with generating demo compiler IR. Still need to wire up `std::simd` support.

https://salsa.debian.org/Kazan-team/vector-math/-/blob/7975aa9639f3a5a702b130a7cf992ffe71c86e2a/src/ir.rs#L1547
The following Rust:
```rust
fn f<Ctx: Context>(ctx: Ctx, a: Ctx::VecU8, b: Ctx::VecF32) -> Ctx::VecF64 {
    let a: Ctx::VecF32 = a.into();
    (a - (a + b - ctx.make(5f32)).floor()).to()
}
```
(the `to()` function is a replacement for the `as` keyword)

Generates the following demo IR:
```
function(in<arg_0>: vec<U8>, in<arg_1>: vec<F32>) -> vec<F64> {
    op_0: vec<F32> = Cast in<arg_0>
    op_1: vec<F32> = Add op_0, in<arg_1>
    op_2: vec<F32> = Sub op_1, splat(0x40A00000_f32)
    op_3: vec<F32> = Floor op_2
    op_4: vec<F32> = Sub op_0, op_3
    op_5: vec<F64> = Cast op_4
    Return op_5
}
```

Opinions on ease of use for writing functions like `f`?
Comment 9 Jacob Lifshay 2021-05-05 11:14:47 BST
From https://github.com/rust-lang/stdsimd/issues/109#issuecomment-832573074
I added bindings for std::simd:
https://salsa.debian.org/Kazan-team/vector-math/-/commit/d77893b257c86d7ddc81f3772b5e143ce768d291
Looking at the assembly generated for stdsimd::tests::do_ilogb_f32x4, it looks pretty reasonable, everything's inlined, however there is still some branching that llvm didn't optimize out:
<snip>
Compiled using:

cargo rustc --release --tests --features=ir,fma,stdsimd -- --emit=asm -C target-cpu=native
on a Ryzen 3900X on Ubuntu
Comment 10 Jacob Lifshay 2021-05-10 08:47:11 BST
From https://github.com/rust-lang/stdsimd/issues/109#issuecomment-836310527
I added implementations of `sin_pi` and `cos_pi` for `f16` and `f32`, I tested all possible inputs, the functions are accurate to 2ULP though aren't guaranteed to give the correct sign for zeros.

Testing the `f32` functions required writing a custom reference implementation of `sin_cos_pi` since `(x * f64::consts::PI).sin_cos()` isn't accurate enough when the exact mathematical value of either `sin` or `cos` is close to zero (e.g. `sin_pi(1.0) == 0.0` but `f64::consts::PI.sin() != 0.0` due to round-off error).

https://salsa.debian.org/Kazan-team/vector-math/-/blob/d79f43bed2398cbc4f6b75b8e55ee317289599a1/src/algorithms/trig_pi.rs#L180
Comment 11 Jacob Lifshay 2021-05-13 01:57:50 BST
Added implementations for sin_pi/cos_pi/sin_cos_pi_f16/f32/f64
Comment 12 Jacob Lifshay 2021-05-13 06:25:48 BST
I added sin_pi and cos_pi for f64, as well as adding abs, copy_sign, and trunc for all of f16/f32/f64.
Comment 13 Luke Kenneth Casson Leighton 2021-05-13 11:51:30 BST
(In reply to Jacob Lifshay from comment #8)

> https://salsa.debian.org/Kazan-team/vector-math/-/blob/
> 7975aa9639f3a5a702b130a7cf992ffe71c86e2a/src/ir.rs#L1547

remember always always always request / create a git.libre-soc.org
repository.

done now
https://git.libre-soc.org/?p=vector-math.git;a=summary
Comment 14 Jacob Lifshay 2021-05-14 02:46:36 BST
(In reply to Luke Kenneth Casson Leighton from comment #13)
> remember always always always request / create a git.libre-soc.org
> repository.
> 
> done now
> https://git.libre-soc.org/?p=vector-math.git;a=summary

I'll manually keep that up to date (setting up mirroring is a pain), but, since vector-math is part of Kazan, the canonical repo location is https://salsa.debian.org/Kazan-team/vector-math
Comment 15 Jacob Lifshay 2021-05-14 04:07:30 BST
I added round_to_nearest_ties_to_even, ceil, floor, and tan_pi
Comment 16 Jacob Lifshay 2021-05-18 05:15:30 BST
Added count_leading_zeros, count_trailing_zeros, and count_ones