Skip to main content

simd_dispatch

Macro simd_dispatch 

Source
macro_rules! simd_dispatch {
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            wasm_simd: $wasm:expr,
            avx2: $avx2:expr,
            neon: $neon:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            wasm_simd: $wasm:expr,
            avx2: $avx2:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            wasm_simd: $wasm:expr,
            neon: $neon:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            avx2: $avx2:expr,
            neon: $neon:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            wasm_simd: $wasm:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            avx2: $avx2:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            neon: $neon:expr,
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis fn $name:ident($($arg:ident: $type:ty),* $(,)?) -> $ret:ty {
            fallback: $fallback:expr $(,)?
        }
    ) => { ... };
}
Expand description

Unified SIMD dispatch macro for compile-time platform selection.

Generates a public function that automatically dispatches to the best available SIMD implementation based on compile-time target architecture and feature flags.

§Syntax

simd_dispatch! {
    $(#[$attr:meta])*           // Optional attributes (doc comments, #[inline], etc.)
    $vis fn $name($args) -> $ret {
        wasm_simd: $wasm_expr,  // Optional: WASM SIMD128 implementation
        avx2: $avx2_expr,       // Optional: x86_64 AVX2 implementation
        neon: $neon_expr,       // Optional: ARM NEON implementation
        fallback: $fallback_expr, // REQUIRED: Scalar fallback
    }
}

§Branch Order

Branches are matched in this priority order:

  1. wasm_simd - Compiled for wasm32 with simd128 feature
  2. avx2 - Compiled for x86_64 with avx2 feature
  3. neon - Compiled for aarch64
  4. fallback - All other platforms (always required)

§Generated Code

The macro expands to a cfg_if::cfg_if! block with compile-time platform detection. Each branch is only compiled for its target.

§Example: Full Dispatch

simd_dispatch! {
    /// Compute Hamming distance with SIMD acceleration.
    #[inline]
    #[must_use]
    pub fn hamming_distance(a: &[u8], b: &[u8]) -> u32 {
        wasm_simd: wasm::hamming_distance(a, b),
        avx2: unsafe { x86::hamming_distance(a, b) },
        neon: neon::hamming_distance(a, b),
        fallback: scalar::hamming_distance(a, b),
    }
}

§Example: Partial Dispatch

simd_dispatch! {
    // Only WASM and AVX2, no NEON
    pub fn l2_squared(a: &[f32], b: &[f32]) -> f32 {
        wasm_simd: wasm::l2_squared(a, b),
        avx2: x86::l2_squared(a, b),
        fallback: scalar::l2_squared(a, b),
    }
}

§Notes

  • The fallback branch is always required
  • All branches must return the same type
  • Use unsafe { } when calling unsafe SIMD intrinsics
  • Attributes like #[inline], #[must_use], and doc comments are preserved