Crate fearless_simd

Source
Expand description

A helper library to make SIMD more friendly.

Fearless SIMD exposes safe SIMD with ergonomic multi-versioning in Rust.

Fearless SIMD uses “marker values” which serve as proofs of which target features are available on the current CPU. These each implement the Simd trait, which exposes a core set of SIMD operations which are implemented as efficiently as possible on each target platform.

Additionally, there are types for packed vectors of a specific width and element type (such as f32x4). Fearless SIMD does not currently support vectors of less than 128 bits. These vector types implement some standard arithmetic traits (i.e. they can be added together using +, multiplied by a scalar using *, among others), which are implemented as efficiently as possible using SIMD instructions. These can be created in a SIMD context using the SimdFrom trait, or the from_slice associated function.

To create a function which SIMD and can be multiversioned, it will have a signature like:

use fearless_simd::{Simd, simd_dispatch};

#[inline(always)]
fn sigmoid_impl<S: Simd>(simd: S, x: &[f32], out: &mut [f32]) { /* ... */ }

simd_dispatch!(sigmoid(level, x: &[f32], out: &mut [f32]) = sigmoid_impl);

A few things to note:

  1. This is generic over any Simd type.
  2. The simd_dispatch macro is used to create a multi-versioned version of the given function.
  3. The _impl suffix is used by convention to indicate the version of a function which will be dispatched to.
  4. The impl function must be #[inline(always)]. The performance of the SIMD implementation will be poor if that isn’t the case. See the section on inlining for details

The signature of the generated function will be:

use fearless_simd::Level;
fn sigmoid(level: Level, x: &[f32], out: &mut [f32]) { /* ... */ }

The first parameter to this function is the Level. If you are writing an application, you should create this once (using Level::new), and pass it to any function which wants to use SIMD. This type stores which instruction sets are available for the current process, which is used in the (generated) sigmoid function to dispatch to the most optimal variant of the function for this process.

§Inlining

Fearless SIMD relies heavily on Rust’s inlining support to create functions which have the given target features enabled. As such, most functions which you write when using Fearless SIMD should have the #[inline(always)] attribute. This is required because in LLVM, functions with different target features cannot.

§Webassembly

WASM SIMD doesn’t have feature detection, and so you need to compile two versions of your bundle for WASM, one with SIMD and one without, then select the appropriate one for your user’s browser. TODO: Expand on this.

§Feature Flags

The following crate feature flags are available:

  • std (enabled by default): Get floating point functions from the standard library (likely using your target’s libc).
  • libm: Use floating point implementations from [libm].
  • safe_wrappers: Include safe wrappers for (some) target feature specific intrinsics, beyond the basic SIMD operations abstracted on all platforms.

At least one of std and libm is required; std overrides libm.

Modules§

core_arch
Access to architecture-specific intrinsics.
generated 🔒
A module containing generated files
impl_macros 🔒
Macros used by implementations
macros 🔒
Macros publicly exported
traits 🔒
x86
Implementations of Simd on x86 architectures (both 32 and 64 bit).

Macros§

simd_dispatch

Structs§

Avx2
The SIMD token for the “AVX2” and “FMA” level.
Fallback
The SIMD token for the “fallback” level.
Sse4_2
The SIMD token for the “SSE 4.2” level.
f32x4
f32x8
f32x16
f64x2
f64x4
f64x8
i8x16
i8x32
i8x64
i16x8
i16x16
i16x32
i32x4
i32x8
i32x16
mask8x16
mask8x32
mask8x64
mask16x8
mask16x16
mask16x32
mask32x4
mask32x8
mask32x16
mask64x2
mask64x4
mask64x8
u8x16
u8x32
u8x64
u16x8
u16x16
u16x32
u32x4
u32x8
u32x16

Enums§

Level
The level enum with the specific SIMD capabilities available.

Traits§

Bytes
Select
Simd
TODO: docstring
SimdBase
SimdCvtFloat
Construction of floating point vectors from integers
SimdCvtTruncate
Construction of integer vectors from floats by truncation
SimdElement
SimdFloat
SimdFrom
Value conversion, adding a SIMD blessing.
SimdInt
SimdInto
Value conversion, adding a SIMD blessing.
SimdMask
WithSimd