{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MagicHash #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Data.Primitive.SIMD.Class where -- This code was AUTOMATICALLY generated, DO NOT EDIT! import Control.Monad.Primitive import Data.Primitive import GHC.Exts -- | The compiler only supports tuples up to 62 elements, so we have to use our own data type. data Tuple64 a = Tuple64 a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- * SIMD type classes -- | This class provides basic operations to create and consume SIMD types. -- Numeric operations on members of this class should compile to single -- SIMD instructions although not all operations are (yet) supported by -- GHC (e.g. 'sqrt', it is currently implemented as @mapVector sqrt@ which -- has to unpack the vector, compute the results and pack them again). class (Num v, Real (Elem v)) => SIMDVector v where -- | Type of the elements in the vector type Elem v -- | Type used to pack or unpack the vector type ElemTuple v -- | Vector with all elements initialized to zero. nullVector :: v -- | Number of components (scalar elements) in the vector. The argument is not evaluated. vectorSize :: v -> Int -- | Size of each (scalar) element in the vector in bytes. The argument is not evaluated. elementSize :: v -> Int -- | Broadcast a scalar to all elements of a vector. broadcastVector :: Elem v -> v -- | Insert a scalar at the given position (starting from 0) in a vector. If the index is outside of the range an exception is thrown. insertVector :: v -> Elem v -> Int -> v insertVector v e i | i < 0 = error $ "insertVector: negative argument: " ++ show i | i < vectorSize v = unsafeInsertVector v e i | otherwise = error $ "insertVector: argument too large: " ++ show i -- | Insert a scalar at the given position (starting from 0) in a vector. If the index is outside of the range the behavior is undefined. unsafeInsertVector :: v -> Elem v -> Int -> v -- | Apply a function to each element of a vector. Be very careful not to map -- branching functions over a vector as they could lead to quite a bit of -- code bloat (or make sure they are tagged with NOINLINE). mapVector :: (Elem v -> Elem v) -> v -> v -- | Zip two vectors together using a combining function. zipVector :: (Elem v -> Elem v -> Elem v) -> v -> v -> v -- | Fold the elements of a vector to a single value. The order in which -- the elements are combined is not specified. foldVector :: (Elem v -> Elem v -> Elem v) -> v -> Elem v -- | Sum up the components of the vector. Equivalent to @foldVector (+)@. sumVector :: v -> Elem v sumVector = foldVector (+) -- | Pack some elements to a vector. packVector :: ElemTuple v -> v -- | Unpack a vector. unpackVector :: v -> ElemTuple v -- | Provides vectorized versions of 'quot' and 'rem'. Implementing their -- type class is not possible for SIMD types as it would require -- implementing 'toInteger'. class SIMDVector v => SIMDIntVector v where -- | Rounds towards zero element-wise. quotVector :: v -> v -> v -- | Satisfies @(quotVector x y) * y + (remVector x y) == x@. remVector :: v -> v -> v {-# INLINE setByteArrayGeneric #-} setByteArrayGeneric :: (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> Int -> a -> m () setByteArrayGeneric mba off n v | n <= 0 = return () | otherwise = do writeByteArray mba off v setByteArrayGeneric mba (off + 1) (n - 1) v {-# INLINE setOffAddrGeneric #-} setOffAddrGeneric :: (Prim a, PrimMonad m) => Addr -> Int -> Int -> a -> m () setOffAddrGeneric addr off n v | n <= 0 = return () | otherwise = do writeOffAddr addr off v setOffAddrGeneric addr (off + 1) (n - 1) v {-# RULES "unpack/pack Int8X16#" forall x . unpackInt8X16# (packInt8X16# x) = x #-} {-# RULES "pack/unpack Int8X16#" forall x . packInt8X16# (unpackInt8X16# x) = x #-} {-# RULES "unpack/pack Int8X32#" forall x . unpackInt8X32# (packInt8X32# x) = x #-} {-# RULES "pack/unpack Int8X32#" forall x . packInt8X32# (unpackInt8X32# x) = x #-} {-# RULES "unpack/pack Int8X64#" forall x . unpackInt8X64# (packInt8X64# x) = x #-} {-# RULES "pack/unpack Int8X64#" forall x . packInt8X64# (unpackInt8X64# x) = x #-} {-# RULES "unpack/pack Int16X8#" forall x . unpackInt16X8# (packInt16X8# x) = x #-} {-# RULES "pack/unpack Int16X8#" forall x . packInt16X8# (unpackInt16X8# x) = x #-} {-# RULES "unpack/pack Int16X16#" forall x . unpackInt16X16# (packInt16X16# x) = x #-} {-# RULES "pack/unpack Int16X16#" forall x . packInt16X16# (unpackInt16X16# x) = x #-} {-# RULES "unpack/pack Int16X32#" forall x . unpackInt16X32# (packInt16X32# x) = x #-} {-# RULES "pack/unpack Int16X32#" forall x . packInt16X32# (unpackInt16X32# x) = x #-} {-# RULES "unpack/pack Int32X4#" forall x . unpackInt32X4# (packInt32X4# x) = x #-} {-# RULES "pack/unpack Int32X4#" forall x . packInt32X4# (unpackInt32X4# x) = x #-} {-# RULES "unpack/pack Int32X8#" forall x . unpackInt32X8# (packInt32X8# x) = x #-} {-# RULES "pack/unpack Int32X8#" forall x . packInt32X8# (unpackInt32X8# x) = x #-} {-# RULES "unpack/pack Int32X16#" forall x . unpackInt32X16# (packInt32X16# x) = x #-} {-# RULES "pack/unpack Int32X16#" forall x . packInt32X16# (unpackInt32X16# x) = x #-} {-# RULES "unpack/pack Int64X2#" forall x . unpackInt64X2# (packInt64X2# x) = x #-} {-# RULES "pack/unpack Int64X2#" forall x . packInt64X2# (unpackInt64X2# x) = x #-} {-# RULES "unpack/pack Int64X4#" forall x . unpackInt64X4# (packInt64X4# x) = x #-} {-# RULES "pack/unpack Int64X4#" forall x . packInt64X4# (unpackInt64X4# x) = x #-} {-# RULES "unpack/pack Int64X8#" forall x . unpackInt64X8# (packInt64X8# x) = x #-} {-# RULES "pack/unpack Int64X8#" forall x . packInt64X8# (unpackInt64X8# x) = x #-} {-# RULES "unpack/pack Word8X16#" forall x . unpackWord8X16# (packWord8X16# x) = x #-} {-# RULES "pack/unpack Word8X16#" forall x . packWord8X16# (unpackWord8X16# x) = x #-} {-# RULES "unpack/pack Word8X32#" forall x . unpackWord8X32# (packWord8X32# x) = x #-} {-# RULES "pack/unpack Word8X32#" forall x . packWord8X32# (unpackWord8X32# x) = x #-} {-# RULES "unpack/pack Word8X64#" forall x . unpackWord8X64# (packWord8X64# x) = x #-} {-# RULES "pack/unpack Word8X64#" forall x . packWord8X64# (unpackWord8X64# x) = x #-} {-# RULES "unpack/pack Word16X8#" forall x . unpackWord16X8# (packWord16X8# x) = x #-} {-# RULES "pack/unpack Word16X8#" forall x . packWord16X8# (unpackWord16X8# x) = x #-} {-# RULES "unpack/pack Word16X16#" forall x . unpackWord16X16# (packWord16X16# x) = x #-} {-# RULES "pack/unpack Word16X16#" forall x . packWord16X16# (unpackWord16X16# x) = x #-} {-# RULES "unpack/pack Word16X32#" forall x . unpackWord16X32# (packWord16X32# x) = x #-} {-# RULES "pack/unpack Word16X32#" forall x . packWord16X32# (unpackWord16X32# x) = x #-} {-# RULES "unpack/pack Word32X4#" forall x . unpackWord32X4# (packWord32X4# x) = x #-} {-# RULES "pack/unpack Word32X4#" forall x . packWord32X4# (unpackWord32X4# x) = x #-} {-# RULES "unpack/pack Word32X8#" forall x . unpackWord32X8# (packWord32X8# x) = x #-} {-# RULES "pack/unpack Word32X8#" forall x . packWord32X8# (unpackWord32X8# x) = x #-} {-# RULES "unpack/pack Word32X16#" forall x . unpackWord32X16# (packWord32X16# x) = x #-} {-# RULES "pack/unpack Word32X16#" forall x . packWord32X16# (unpackWord32X16# x) = x #-} {-# RULES "unpack/pack Word64X2#" forall x . unpackWord64X2# (packWord64X2# x) = x #-} {-# RULES "pack/unpack Word64X2#" forall x . packWord64X2# (unpackWord64X2# x) = x #-} {-# RULES "unpack/pack Word64X4#" forall x . unpackWord64X4# (packWord64X4# x) = x #-} {-# RULES "pack/unpack Word64X4#" forall x . packWord64X4# (unpackWord64X4# x) = x #-} {-# RULES "unpack/pack Word64X8#" forall x . unpackWord64X8# (packWord64X8# x) = x #-} {-# RULES "pack/unpack Word64X8#" forall x . packWord64X8# (unpackWord64X8# x) = x #-} {-# RULES "unpack/pack FloatX4#" forall x . unpackFloatX4# (packFloatX4# x) = x #-} {-# RULES "pack/unpack FloatX4#" forall x . packFloatX4# (unpackFloatX4# x) = x #-} {-# RULES "unpack/pack FloatX8#" forall x . unpackFloatX8# (packFloatX8# x) = x #-} {-# RULES "pack/unpack FloatX8#" forall x . packFloatX8# (unpackFloatX8# x) = x #-} {-# RULES "unpack/pack FloatX16#" forall x . unpackFloatX16# (packFloatX16# x) = x #-} {-# RULES "pack/unpack FloatX16#" forall x . packFloatX16# (unpackFloatX16# x) = x #-} {-# RULES "unpack/pack DoubleX2#" forall x . unpackDoubleX2# (packDoubleX2# x) = x #-} {-# RULES "pack/unpack DoubleX2#" forall x . packDoubleX2# (unpackDoubleX2# x) = x #-} {-# RULES "unpack/pack DoubleX4#" forall x . unpackDoubleX4# (packDoubleX4# x) = x #-} {-# RULES "pack/unpack DoubleX4#" forall x . packDoubleX4# (unpackDoubleX4# x) = x #-} {-# RULES "unpack/pack DoubleX8#" forall x . unpackDoubleX8# (packDoubleX8# x) = x #-} {-# RULES "pack/unpack DoubleX8#" forall x . packDoubleX8# (unpackDoubleX8# x) = x #-}