Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm32 support #66

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
[build]
# rustflags = "-C target-cpu=native"
# target = "aarch64-unknown-linux-gnu"
# target = "wasm32-wasi"

[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))']
rustflags = "-C target-feature=-sse4.1,-avx,-sse3"

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

[target.wasm32-wasi]
runner = "wasmtime"
rustflags = "-C target-feature=+simd128"

[registries.crates-io]
protocol = "sparse"
29 changes: 29 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,32 @@ jobs:
with:
command: test
args: --release --target aarch64-unknown-linux-gnu

wasm_tests:
name: WebAssembly Tests
runs-on: ubuntu-latest
env:
WASMTIME_BACKTRACE_DETAILS: 1
steps:
- uses: actions/checkout@v2

- name: Setup `wasmtime`
uses: bytecodealliance/actions/wasmtime/setup@v1

- uses: actions-rs/toolchain@v1
name: Initialize Cargo
with:
profile: minimal
toolchain: stable
target: wasm32-wasi
override: true
components: rustfmt, clippy

- uses: Swatinem/rust-cache@v2
name: Cargo Cache

- uses: actions-rs/cargo@v1
name: Run tests (release)
with:
command: test
args: --release --target wasm32-wasi
12 changes: 10 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ readme = "README.md"
keywords = ["SIMD", "avx2", "sse", "performance", "no_std"]
repository = "https://github.com/jackmott/simdeez"
categories = ["hardware-support", "science", "game-engines"]
edition = "2018"
edition = "2021"

[lib]
doctest = false
Expand All @@ -29,7 +29,15 @@ libm = { version = "0.2.6", optional = true }
[dev-dependencies]
rand = "0.8.5"
rand_chacha = "0.3.1"
criterion = "0.4.0"

[target.'cfg(not(target_family = "wasm"))'.dev-dependencies.criterion]
version = "0.4.0"

[target.'cfg(target_family = "wasm")'.dev-dependencies.criterion]
version = "0.4.0"
default-features = false
# Default features, excluding `rayon` which isn't supported on WASM
features = ["plotters", "cargo_bench_support"]

[[bench]]
name = "numparse"
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
A library that abstracts over SIMD instruction sets, including ones with differing widths.
SIMDeez is designed to allow you to write a function one time and produce SSE2, SSE41, and AVX2 versions of the function.
SIMDeez is designed to allow you to write a function one time and produce SSE2, SSE41, AVX2, NEON and WebAssembly SIMD versions of the function.
You can either have the version you want chosen at compile time or automatically at runtime.

Originally developed by @jackmott, however I volunteered to take over ownership.

If there are intrinsics you need that are not currently implemented, create an issue
and I'll add them. PRs to add more intrinsics are welcome. Currently things are well fleshed out for i32, i64, f32, and f64 types.
If there are intrinsics you need that are not currently implemented, create an issue and I'll add them. PRs to add more intrinsics are welcome. Currently things are well fleshed out for i32, i64, f32, and f64 types.

As Rust stabilizes support for Neon and AVX-512 I plan to add those as well.
As Rust stabilizes support for AVX-512 I plan to add those as well.

Refer to the excellent [Intel Intrinsics Guide](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#) for documentation on these functions:

# Features

* SSE2, SSE41, AVX and AVX2, and scalar fallback
* SSE2, SSE41, AVX and AVX2, NEON, WebAssembly SIMD and scalar fallback
* Can be used with compile time or run time selection
* No runtime overhead
* Uses familiar intel intrinsic naming conventions, easy to port.
* `_mm_add_ps(a,b)` becomes `add_ps(a,b)`
* Fills in missing intrinsics in older APIs with fast SIMD workarounds.
* ceil, floor, round,blend etc
* ceil, floor, round, blend, etc.
* Can be used by `#[no_std]` projects
* Operator overloading: `let sum = va + vb` or `s *= s`
* Extract or set a single lane with the index operator: `let v1 = v[1];`
Expand Down
28 changes: 21 additions & 7 deletions src/base/transmute.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#[cfg(target_arch = "aarch64")]
use core::arch::aarch64::*;
#[cfg(target_arch = "wasm32")]
use core::arch::wasm32::v128;
#[cfg(target_arch = "x86")]
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;

macro_rules! make_simd_transmute {
($name:ident, $scalar:ident, $sse:ident, $avx:ident, $neon:ident) => {
($name:ident, $scalar:ident, $sse:ident, $avx:ident, $neon:ident, $wasm:ident) => {
pub trait $name: Sized {
/// Tries to transmute the value into its underlying scalar type. Panics if the value is not a scalar.
fn try_transmute_scalar(&self) -> $scalar {
Expand Down Expand Up @@ -65,13 +67,25 @@ macro_rules! make_simd_transmute {
fn try_transmute_from_neon(_neon: $neon) -> Self {
panic!("Invalid transmute: tried to transmute non-neon into neon");
}

#[cfg(target_arch = "wasm32")]
/// Tries to transmute the value into its underlying Wasm type. Panics if the value is not a Wasm.
fn try_transmute_wasm(&self) -> $wasm {
panic!("Invalid transmute: tried to transmute non-wasm into wasm");
}

#[cfg(target_arch = "wasm32")]
/// Tries to create the value from its underlying Wasm type. Panics if the value is not a Wasm.
fn try_transmute_from_wasm(_wasm: $wasm) -> Self {
panic!("Invalid transmute: tried to transmute non-wasm into wasm");
}
}
};
}

make_simd_transmute!(SimdTransmuteF32, f32, __m128, __m256, float32x4_t);
make_simd_transmute!(SimdTransmuteF64, f64, __m128d, __m256d, float64x2_t);
make_simd_transmute!(SimdTransmuteI8, i8, __m128i, __m256i, int8x16_t);
make_simd_transmute!(SimdTransmuteI16, i16, __m128i, __m256i, int16x8_t);
make_simd_transmute!(SimdTransmuteI32, i32, __m128i, __m256i, int32x4_t);
make_simd_transmute!(SimdTransmuteI64, i64, __m128i, __m256i, int64x2_t);
make_simd_transmute!(SimdTransmuteF32, f32, __m128, __m256, float32x4_t, v128);
make_simd_transmute!(SimdTransmuteF64, f64, __m128d, __m256d, float64x2_t, v128);
make_simd_transmute!(SimdTransmuteI8, i8, __m128i, __m256i, int8x16_t, v128);
make_simd_transmute!(SimdTransmuteI16, i16, __m128i, __m256i, int16x8_t, v128);
make_simd_transmute!(SimdTransmuteI32, i32, __m128i, __m256i, int32x4_t, v128);
make_simd_transmute!(SimdTransmuteI64, i64, __m128i, __m256i, int64x2_t, v128);
31 changes: 0 additions & 31 deletions src/engines/_unused/wasm32/mod.rs

This file was deleted.

Loading