{-# LANGUAGE BangPatterns        #-}
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE MagicHash           #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE PatternSynonyms     #-}
{-# LANGUAGE RoleAnnotations     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE UnboxedTuples       #-}
{-# LANGUAGE ViewPatterns        #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Primitive.Vec
-- Copyright   : [2008..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Primitive.Vec (

  -- * SIMD vector types
  Vec(..),
  Vec2, pattern Vec2,
  Vec3, pattern Vec3,
  Vec4, pattern Vec4,
  Vec8, pattern Vec8,
  Vec16, pattern Vec16,

  listOfVec,
  liftVec,

) where

import Control.Monad.ST
import Data.Primitive.ByteArray
import Data.Primitive.Types
import Data.Text.Prettyprint.Doc
import Language.Haskell.TH
import Language.Haskell.TH.Syntax

import GHC.Base                                                     ( isTrue# )
import GHC.Int
import GHC.Prim
import GHC.TypeLits
import GHC.Word


-- Note: [Representing SIMD vector types]
--
-- A simple polymorphic representation of SIMD types such as the following:
--
-- > data Vec2 a = Vec2 !a !a
--
-- is not able to unpack the values into the constructor, meaning that
-- 'Vec2' is storing pointers to (strict) values on the heap, which is
-- a very inefficient representation.
--
-- We might try defining a data family instead so that we can get efficient
-- unboxed representations, and even make use of the unlifted SIMD types GHC
-- knows about:
--
-- > data family Vec2 a :: *
-- > data instance Vec2 Float    = Vec2_Float Float# Float#   -- reasonable
-- > data instance Vec2 Double   = Vec2_Double DoubleX2#      -- built in!
--
-- However, this runs into the problem that GHC stores all values as word sized
-- entities:
--
-- > data instance Vec2 Int      = Vec2_Int Int# Int#
-- > data instance Vec2 Int8     = Vec2_Int8 Int8# Int8#      -- Int8# does not exist; requires a full Int#
--
-- which, again, is very memory inefficient.
--
-- So, as a last resort, we'll just use a ByteArray# to ensure an efficient
-- packed representation.
--
-- One inefficiency of this approach is that the byte array does track its size,
-- which redundant for our use case (derivable from type level information).
--
data Vec (n :: Nat) a = Vec ByteArray#

type role Vec nominal representational

instance (Show a, Prim a, KnownNat n) => Show (Vec n a) where
  show :: Vec n a -> String
show = [a] -> String
vec ([a] -> String) -> (Vec n a -> [a]) -> Vec n a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vec n a -> [a]
forall a (n :: Nat). (Prim a, KnownNat n) => Vec n a -> [a]
listOfVec
    where
      vec :: [a] -> String
      vec :: [a] -> String
vec = Doc Any -> String
forall a. Show a => a -> String
show
          (Doc Any -> String) -> ([a] -> Doc Any) -> [a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann
group (Doc Any -> Doc Any) -> ([a] -> Doc Any) -> [a] -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> Doc Any -> Doc Any -> [Doc Any] -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann -> [Doc ann] -> Doc ann
encloseSep (Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
flatAlt Doc Any
"< " Doc Any
"<") (Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
flatAlt Doc Any
" >" Doc Any
">") Doc Any
", "
          ([Doc Any] -> Doc Any) -> ([a] -> [Doc Any]) -> [a] -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc Any) -> [a] -> [Doc Any]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc Any
forall a ann. Show a => a -> Doc ann
viaShow

listOfVec :: forall a n. (Prim a, KnownNat n) => Vec n a -> [a]
listOfVec :: Vec n a -> [a]
listOfVec (Vec ByteArray#
ba#) = Int# -> [a]
go Int#
0#
  where
    go :: Int# -> [a]
    go :: Int# -> [a]
go Int#
i# | Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
<# Int#
n#)  = ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
i# a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int# -> [a]
go (Int#
i# Int# -> Int# -> Int#
+# Int#
1#)
          | Bool
otherwise           = []

    !(I# Int#
n#)  = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy# n -> Integer
forall (n :: Nat). KnownNat n => Proxy# n -> Integer
natVal' (Proxy# n
forall k (a :: k). Proxy# a
proxy# :: Proxy# n))

instance Eq (Vec n a) where
  Vec ByteArray#
ba1# == :: Vec n a -> Vec n a -> Bool
== Vec ByteArray#
ba2# = ByteArray# -> ByteArray
ByteArray ByteArray#
ba1# ByteArray -> ByteArray -> Bool
forall a. Eq a => a -> a -> Bool
== ByteArray# -> ByteArray
ByteArray ByteArray#
ba2#

-- Type synonyms for common SIMD vector types
--
-- Note that non-power-of-two sized SIMD vectors are a bit dubious, and
-- special care must be taken in the code generator. For example, LLVM will
-- treat a Vec3 with alignment of _4_, meaning that reads and writes will
-- be (without further action) incorrect.
--
type Vec2 a  = Vec 2 a
type Vec3 a  = Vec 3 a
type Vec4 a  = Vec 4 a
type Vec8 a  = Vec 8 a
type Vec16 a = Vec 16 a

pattern Vec2 :: Prim a => a -> a -> Vec2 a
pattern $bVec2 :: a -> a -> Vec2 a
$mVec2 :: forall r a. Prim a => Vec2 a -> (a -> a -> r) -> (Void# -> r) -> r
Vec2 a b <- (unpackVec2 -> (a,b))
  where Vec2 = a -> a -> Vec2 a
forall a. Prim a => a -> a -> Vec2 a
packVec2
{-# COMPLETE Vec2 #-}

pattern Vec3 :: Prim a => a -> a -> a -> Vec3 a
pattern $bVec3 :: a -> a -> a -> Vec3 a
$mVec3 :: forall r a.
Prim a =>
Vec3 a -> (a -> a -> a -> r) -> (Void# -> r) -> r
Vec3 a b c <- (unpackVec3 -> (a,b,c))
  where Vec3 = a -> a -> a -> Vec3 a
forall a. Prim a => a -> a -> a -> Vec3 a
packVec3
{-# COMPLETE Vec3 #-}

pattern Vec4 :: Prim a => a -> a -> a -> a -> Vec4 a
pattern $bVec4 :: a -> a -> a -> a -> Vec4 a
$mVec4 :: forall r a.
Prim a =>
Vec4 a -> (a -> a -> a -> a -> r) -> (Void# -> r) -> r
Vec4 a b c d <- (unpackVec4 -> (a,b,c,d))
  where Vec4 = a -> a -> a -> a -> Vec4 a
forall a. Prim a => a -> a -> a -> a -> Vec4 a
packVec4
{-# COMPLETE Vec4 #-}

pattern Vec8 :: Prim a => a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
pattern $bVec8 :: a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
$mVec8 :: forall r a.
Prim a =>
Vec8 a
-> (a -> a -> a -> a -> a -> a -> a -> a -> r) -> (Void# -> r) -> r
Vec8 a b c d e f g h <- (unpackVec8 -> (a,b,c,d,e,f,g,h))
  where Vec8 = a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
forall a. Prim a => a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
packVec8
{-# COMPLETE Vec8 #-}

pattern Vec16 :: Prim a => a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> Vec16 a
pattern $bVec16 :: a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> Vec16 a
$mVec16 :: forall r a.
Prim a =>
Vec16 a
-> (a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> a
    -> r)
-> (Void# -> r)
-> r
Vec16 a b c d e f g h i j k l m n o p <- (unpackVec16 -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p))
  where Vec16 = a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> Vec16 a
forall a.
Prim a =>
a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> Vec16 a
packVec16
{-# COMPLETE Vec16 #-}

unpackVec2 :: Prim a => Vec2 a -> (a,a)
unpackVec2 :: Vec2 a -> (a, a)
unpackVec2 (Vec ByteArray#
ba#) =
  ( ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
0#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
1#
  )

unpackVec3 :: Prim a => Vec3 a -> (a,a,a)
unpackVec3 :: Vec3 a -> (a, a, a)
unpackVec3 (Vec ByteArray#
ba#) =
  ( ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
0#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
1#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
2#
  )

unpackVec4 :: Prim a => Vec4 a -> (a,a,a,a)
unpackVec4 :: Vec4 a -> (a, a, a, a)
unpackVec4 (Vec ByteArray#
ba#) =
  ( ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
0#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
1#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
2#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
3#
  )

unpackVec8 :: Prim a => Vec8 a -> (a,a,a,a,a,a,a,a)
unpackVec8 :: Vec8 a -> (a, a, a, a, a, a, a, a)
unpackVec8 (Vec ByteArray#
ba#) =
  ( ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
0#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
1#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
2#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
3#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
4#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
5#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
6#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
7#
  )

unpackVec16 :: Prim a => Vec16 a -> (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a)
unpackVec16 :: Vec16 a -> (a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a)
unpackVec16 (Vec ByteArray#
ba#) =
  ( ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
0#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
1#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
2#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
3#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
4#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
5#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
6#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
7#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
8#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
9#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
10#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
11#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
12#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
13#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
14#
  , ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba# Int#
15#
  )

packVec2 :: Prim a => a -> a -> Vec2 a
packVec2 :: a -> a -> Vec2 a
packVec2 a
a a
b = (forall s. ST s (Vec2 a)) -> Vec2 a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vec2 a)) -> Vec2 a)
-> (forall s. ST s (Vec2 a)) -> Vec2 a
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
mba <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Prim a => a -> Int
sizeOf a
a)
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
0 a
a
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
1 a
b
  ByteArray ByteArray#
ba# <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba
  Vec2 a -> ST s (Vec2 a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vec2 a -> ST s (Vec2 a)) -> Vec2 a -> ST s (Vec2 a)
forall a b. (a -> b) -> a -> b
$! ByteArray# -> Vec2 a
forall (n :: Nat) a. ByteArray# -> Vec n a
Vec ByteArray#
ba#

packVec3 :: Prim a => a -> a -> a -> Vec3 a
packVec3 :: a -> a -> a -> Vec3 a
packVec3 a
a a
b a
c = (forall s. ST s (Vec3 a)) -> Vec3 a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vec3 a)) -> Vec3 a)
-> (forall s. ST s (Vec3 a)) -> Vec3 a
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
mba <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Prim a => a -> Int
sizeOf a
a)
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
0 a
a
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
1 a
b
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
2 a
c
  ByteArray ByteArray#
ba# <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba
  Vec3 a -> ST s (Vec3 a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vec3 a -> ST s (Vec3 a)) -> Vec3 a -> ST s (Vec3 a)
forall a b. (a -> b) -> a -> b
$! ByteArray# -> Vec3 a
forall (n :: Nat) a. ByteArray# -> Vec n a
Vec ByteArray#
ba#

packVec4 :: Prim a => a -> a -> a -> a -> Vec4 a
packVec4 :: a -> a -> a -> a -> Vec4 a
packVec4 a
a a
b a
c a
d = (forall s. ST s (Vec4 a)) -> Vec4 a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vec4 a)) -> Vec4 a)
-> (forall s. ST s (Vec4 a)) -> Vec4 a
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
mba <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Prim a => a -> Int
sizeOf a
a)
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
0 a
a
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
1 a
b
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
2 a
c
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
3 a
d
  ByteArray ByteArray#
ba# <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba
  Vec4 a -> ST s (Vec4 a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vec4 a -> ST s (Vec4 a)) -> Vec4 a -> ST s (Vec4 a)
forall a b. (a -> b) -> a -> b
$! ByteArray# -> Vec4 a
forall (n :: Nat) a. ByteArray# -> Vec n a
Vec ByteArray#
ba#

packVec8 :: Prim a => a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
packVec8 :: a -> a -> a -> a -> a -> a -> a -> a -> Vec8 a
packVec8 a
a a
b a
c a
d a
e a
f a
g a
h = (forall s. ST s (Vec8 a)) -> Vec8 a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vec8 a)) -> Vec8 a)
-> (forall s. ST s (Vec8 a)) -> Vec8 a
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
mba <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Prim a => a -> Int
sizeOf a
a)
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
0 a
a
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
1 a
b
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
2 a
c
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
3 a
d
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
4 a
e
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
5 a
f
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
6 a
g
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
7 a
h
  ByteArray ByteArray#
ba# <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba
  Vec8 a -> ST s (Vec8 a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vec8 a -> ST s (Vec8 a)) -> Vec8 a -> ST s (Vec8 a)
forall a b. (a -> b) -> a -> b
$! ByteArray# -> Vec8 a
forall (n :: Nat) a. ByteArray# -> Vec n a
Vec ByteArray#
ba#

packVec16 :: Prim a => a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> Vec16 a
packVec16 :: a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> Vec16 a
packVec16 a
a a
b a
c a
d a
e a
f a
g a
h a
i a
j a
k a
l a
m a
n a
o a
p = (forall s. ST s (Vec16 a)) -> Vec16 a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vec16 a)) -> Vec16 a)
-> (forall s. ST s (Vec16 a)) -> Vec16 a
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
mba <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int
16 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Prim a => a -> Int
sizeOf a
a)
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
0 a
a
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
1 a
b
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
2 a
c
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
3 a
d
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
4 a
e
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
5 a
f
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
6 a
g
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
7 a
h
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
8 a
i
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
9 a
j
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
10 a
k
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
11 a
l
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
12 a
m
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
13 a
n
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
14 a
o
  MutableByteArray (PrimState (ST s)) -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba Int
15 a
p
  ByteArray ByteArray#
ba# <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
mba
  Vec16 a -> ST s (Vec16 a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vec16 a -> ST s (Vec16 a)) -> Vec16 a -> ST s (Vec16 a)
forall a b. (a -> b) -> a -> b
$! ByteArray# -> Vec16 a
forall (n :: Nat) a. ByteArray# -> Vec n a
Vec ByteArray#
ba#

-- O(n) at runtime to copy from the Addr# to the ByteArray#. We should be able
-- to do this without copying, but I don't think the definition of ByteArray# is
-- exported (or it is deeply magical).
--
liftVec :: Vec n a -> Q (TExp (Vec n a))
liftVec :: Vec n a -> Q (TExp (Vec n a))
liftVec (Vec ByteArray#
ba#)
  = Q Exp -> Q (TExp (Vec n a))
forall a. Q Exp -> Q (TExp a)
unsafeTExpCoerce
    [| runST $ \s ->
         case newByteArray# $(liftInt# n#) s                                             of { (# s1, mba# #) ->
         case copyAddrToByteArray# $(litE (StringPrimL bytes)) mba# 0# $(liftInt# n#) s1 of { s2             ->
         case unsafeFreezeByteArray# mba# s2                                             of { (# s3, ba'# #) ->
           (# s3, Vec ba'# #)
        }}}
     |]
  where
      bytes :: [Word8]
      bytes :: [Word8]
bytes = Int# -> [Word8]
go Int#
0#
        where
          go :: Int# -> [Word8]
go Int#
i# | Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
<# Int#
n#) = Word# -> Word8
W8# (ByteArray# -> Int# -> Word#
indexWord8Array# ByteArray#
ba# Int#
i#) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: Int# -> [Word8]
go (Int#
i# Int# -> Int# -> Int#
+# Int#
1#)
                | Bool
otherwise          = []

      n# :: Int#
n# = ByteArray# -> Int#
sizeofByteArray# ByteArray#
ba#

      -- XXX: Typed TH does not support unlifted types
      --
      liftInt# :: Int# -> ExpQ
      liftInt# :: Int# -> Q Exp
liftInt# Int#
i# = Lit -> Q Exp
litE (Integer -> Lit
IntPrimL (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int# -> Int
I# Int#
i#)))