{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{- |
Represent a vector of Stereo values in two vectors
that store the values in an interleaved way.
That is:

> vector0[0] = left[0]
> vector0[1] = right[0]
> vector0[2] = left[1]
> vector0[3] = right[1]
> vector1[0] = left[2]
> vector1[1] = right[2]
> vector1[2] = left[3]
> vector1[3] = right[3]

This representation is not very useful for computation,
but necessary as intermediate representation for interfacing with memory.
SSE/SSE2 have the instructions UNPACK(L|H)P(S|D) that interleave efficiently.
-}
module Synthesizer.LLVM.Frame.StereoInterleavedCode (
   T,
   Value,
   interleave,
   deinterleave,
   fromMono,
   assemble, dissect,
   zero,
   scale,
   amplify,
   envelope,
   ) where

import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
import qualified Synthesizer.LLVM.Frame.SerialVector.Code as Serial

import qualified LLVM.Extra.Multi.Vector as MultiVector
import qualified LLVM.Extra.Multi.Value.Storable as Storable
import qualified LLVM.Extra.Multi.Value.Marshal as Marshal
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Core as LLVM
import LLVM.Core (Vector)

import qualified Type.Data.Num.Decimal as TypeNum

import qualified Foreign.Storable as St
import Foreign.Ptr (Ptr, castPtr)

import qualified Control.Applicative.HT as AppHT
import Control.Applicative (liftA2, pure)

import qualified Data.Foldable as Fold
import Data.Tuple.HT (mapPair)

import qualified Algebra.Additive as Additive


data T n a = Cons (Vector n a) (Vector n a)

type Value n a = MultiValue.T (T n a)


withSize :: (TypeNum.Natural n) => (Int -> m (Value n a)) -> m (Value n a)
withSize :: forall n (m :: * -> *) a.
Natural n =>
(Int -> m (Value n a)) -> m (Value n a)
withSize =
   let sz ::
          (TypeNum.Natural n) =>
          TypeNum.Singleton n -> (Int -> m (Value n a)) -> m (Value n a)
       sz :: forall n (m :: * -> *) a.
Natural n =>
Singleton n -> (Int -> m (Value n a)) -> m (Value n a)
sz Singleton n
n Int -> m (Value n a)
f = Int -> m (Value n a)
f (Singleton n -> Int
forall n a. (Integer n, Num a) => Singleton n -> a
TypeNum.integralFromSingleton Singleton n
n)
   in  Singleton n -> (Int -> m (Value n a)) -> m (Value n a)
forall n (m :: * -> *) a.
Natural n =>
Singleton n -> (Int -> m (Value n a)) -> m (Value n a)
sz Singleton n
forall x. Integer x => Singleton x
TypeNum.singleton


interleave ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Stereo.T (Serial.Value n a) ->
   LLVM.CodeGenFunction r (Value n a)
interleave :: forall n a r.
(Positive n, C a) =>
T (Value n a) -> CodeGenFunction r (Value n a)
interleave T (Value n a)
x =
   [T (T a)] -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, C a) =>
[T (T a)] -> CodeGenFunction r (Value n a)
assemble ([T (T a)] -> CodeGenFunction r (Value n a))
-> ([T (T a)] -> [T (T a)])
-> [T (T a)]
-> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T (T a) -> T (T a)) -> [T (T a)] -> [T (T a)]
forall a b. (a -> b) -> [a] -> [b]
map T (T a) -> T (T a)
forall a. T (T a) -> T (T a)
Stereo.unMultiValue
      ([T (T a)] -> CodeGenFunction r (Value n a))
-> CodeGenFunction r [T (T a)] -> CodeGenFunction r (Value n a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value n (T a) -> CodeGenFunction r [T (T a)]
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r [T a]
Serial.dissect (T (Value n a) -> Value n (T a)
forall n a. T (T (T n a)) -> T (T n (T a))
Stereo.multiValueSerial T (Value n a)
x)

deinterleave ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Value n a ->
   LLVM.CodeGenFunction r (Stereo.T (Serial.Value n a))
deinterleave :: forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r (T (Value n a))
deinterleave Value n a
v =
   T (T n (T a)) -> T (T (T n a))
forall n a. T (T n (T a)) -> T (T (T n a))
Stereo.unMultiValueSerial (T (T n (T a)) -> T (T (T n a)))
-> CodeGenFunction r (T (T n (T a)))
-> CodeGenFunction r (T (T (T n a)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
      ([T (T a)] -> CodeGenFunction r (T (T n (T a)))
forall n a r.
(Positive n, C a) =>
[T a] -> CodeGenFunction r (Value n a)
Serial.assemble ([T (T a)] -> CodeGenFunction r (T (T n (T a))))
-> ([T (T a)] -> [T (T a)])
-> [T (T a)]
-> CodeGenFunction r (T (T n (T a)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T (T a) -> T (T a)) -> [T (T a)] -> [T (T a)]
forall a b. (a -> b) -> [a] -> [b]
map T (T a) -> T (T a)
forall a. T (T a) -> T (T a)
Stereo.multiValue ([T (T a)] -> CodeGenFunction r (T (T n (T a))))
-> CodeGenFunction r [T (T a)] -> CodeGenFunction r (T (T n (T a)))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value n a -> CodeGenFunction r [T (T a)]
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r [T (T a)]
dissect Value n a
v)

fromMono ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Serial.Value n a ->
   LLVM.CodeGenFunction r (Value n a)
fromMono :: forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r (Value n a)
fromMono Value n a
x =
   [T (T a)] -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, C a) =>
[T (T a)] -> CodeGenFunction r (Value n a)
assemble ([T (T a)] -> CodeGenFunction r (Value n a))
-> ([T a] -> [T (T a)]) -> [T a] -> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T a -> T (T a)) -> [T a] -> [T (T a)]
forall a b. (a -> b) -> [a] -> [b]
map T a -> T (T a)
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([T a] -> CodeGenFunction r (Value n a))
-> CodeGenFunction r [T a] -> CodeGenFunction r (Value n a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value n a -> CodeGenFunction r [T a]
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r [T a]
Serial.dissect Value n a
x

assemble ::
   (TypeNum.Positive n, MultiVector.C a) =>
   [Stereo.T (MultiValue.T a)] -> LLVM.CodeGenFunction r (Value n a)
assemble :: forall n a r.
(Positive n, C a) =>
[T (T a)] -> CodeGenFunction r (Value n a)
assemble [T (T a)]
x =
   (Int -> CodeGenFunction r (Value n a))
-> CodeGenFunction r (Value n a)
forall n (m :: * -> *) a.
Natural n =>
(Int -> m (Value n a)) -> m (Value n a)
withSize ((Int -> CodeGenFunction r (Value n a))
 -> CodeGenFunction r (Value n a))
-> (Int -> CodeGenFunction r (Value n a))
-> CodeGenFunction r (Value n a)
forall a b. (a -> b) -> a -> b
$ \Int
n ->
      (CodeGenFunction r (T n a)
 -> CodeGenFunction r (T n a) -> CodeGenFunction r (Value n a))
-> (CodeGenFunction r (T n a), CodeGenFunction r (T n a))
-> CodeGenFunction r (Value n a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((T n a -> T n a -> Value n a)
-> CodeGenFunction r (T n a)
-> CodeGenFunction r (T n a)
-> CodeGenFunction r (Value n a)
forall a b c.
(a -> b -> c)
-> CodeGenFunction r a
-> CodeGenFunction r b
-> CodeGenFunction r c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 T n a -> T n a -> Value n a
forall n a. T n a -> T n a -> T (T n a)
merge) ((CodeGenFunction r (T n a), CodeGenFunction r (T n a))
 -> CodeGenFunction r (Value n a))
-> ([T (T a)]
    -> (CodeGenFunction r (T n a), CodeGenFunction r (T n a)))
-> [T (T a)]
-> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      ([T a] -> CodeGenFunction r (T n a),
 [T a] -> CodeGenFunction r (T n a))
-> ([T a], [T a])
-> (CodeGenFunction r (T n a), CodeGenFunction r (T n a))
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair ([T a] -> CodeGenFunction r (T n a)
forall n a r.
(Positive n, C a) =>
[T a] -> CodeGenFunction r (T n a)
MultiVector.assemble, [T a] -> CodeGenFunction r (T n a)
forall n a r.
(Positive n, C a) =>
[T a] -> CodeGenFunction r (T n a)
MultiVector.assemble) (([T a], [T a])
 -> (CodeGenFunction r (T n a), CodeGenFunction r (T n a)))
-> ([T (T a)] -> ([T a], [T a]))
-> [T (T a)]
-> (CodeGenFunction r (T n a), CodeGenFunction r (T n a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      Int -> [T a] -> ([T a], [T a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n ([T a] -> ([T a], [T a]))
-> ([T (T a)] -> [T a]) -> [T (T a)] -> ([T a], [T a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      (T (T a) -> [T a]) -> [T (T a)] -> [T a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap T (T a) -> [T a]
forall a. T a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList ([T (T a)] -> CodeGenFunction r (Value n a))
-> [T (T a)] -> CodeGenFunction r (Value n a)
forall a b. (a -> b) -> a -> b
$ [T (T a)]
x

dissect ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Value n a -> LLVM.CodeGenFunction r [Stereo.T (MultiValue.T a)]
dissect :: forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r [T (T a)]
dissect Value n a
v =
   let (T n a
v0,T n a
v1) = Value n a -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split Value n a
v in
   ([T a] -> [T (T a)])
-> CodeGenFunction r [T a] -> CodeGenFunction r [T (T a)]
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (let aux :: [a] -> [T a]
aux (a
l:a
r:[a]
xs) = a -> a -> T a
forall a. a -> a -> T a
Stereo.cons a
l a
r T a -> [T a] -> [T a]
forall a. a -> [a] -> [a]
: [a] -> [T a]
aux [a]
xs
           aux [] = []
           aux [a]
_ = [Char] -> [T a]
forall a. HasCallStack => [Char] -> a
error [Char]
"odd number of stereo elements"
       in  [T a] -> [T (T a)]
forall {a}. [a] -> [T a]
aux) (CodeGenFunction r [T a] -> CodeGenFunction r [T (T a)])
-> CodeGenFunction r [T a] -> CodeGenFunction r [T (T a)]
forall a b. (a -> b) -> a -> b
$
   ([T a] -> [T a] -> [T a])
-> CodeGenFunction r [T a]
-> CodeGenFunction r [T a]
-> CodeGenFunction r [T a]
forall a b c.
(a -> b -> c)
-> CodeGenFunction r a
-> CodeGenFunction r b
-> CodeGenFunction r c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 [T a] -> [T a] -> [T a]
forall a. [a] -> [a] -> [a]
(++)
      (T n a -> CodeGenFunction r [T a]
forall n a r. (Positive n, C a) => T n a -> CodeGenFunction r [T a]
MultiVector.dissect T n a
v0)
      (T n a -> CodeGenFunction r [T a]
forall n a r. (Positive n, C a) => T n a -> CodeGenFunction r [T a]
MultiVector.dissect T n a
v1)


merge :: MultiVector.T n a -> MultiVector.T n a -> MultiValue.T (T n a)
merge :: forall n a. T n a -> T n a -> T (T n a)
merge (MultiVector.Cons Repr n a
a) (MultiVector.Cons Repr n a
b) = Repr (T n a) -> T (T n a)
forall a. Repr a -> T a
MultiValue.Cons (Repr n a
a,Repr n a
b)

split :: MultiValue.T (T n a) -> (MultiVector.T n a, MultiVector.T n a)
split :: forall n a. T (T n a) -> (T n a, T n a)
split (MultiValue.Cons (Repr n a
a,Repr n a
b)) = (Repr n a -> T n a
forall n a. Repr n a -> T n a
MultiVector.Cons Repr n a
a, Repr n a -> T n a
forall n a. Repr n a -> T n a
MultiVector.Cons Repr n a
b)

merge_ ::
   MultiValue.T (Vector n a) -> MultiValue.T (Vector n a) ->
   MultiValue.T (T n a)
merge_ :: forall n a. T (Vector n a) -> T (Vector n a) -> T (T n a)
merge_ (MultiValue.Cons Repr (Vector n a)
a) (MultiValue.Cons Repr (Vector n a)
b) = Repr (T n a) -> T (T n a)
forall a. Repr a -> T a
MultiValue.Cons (Repr (Vector n a)
Repr n a
a,Repr (Vector n a)
Repr n a
b)

split_ ::
   MultiValue.T (T n a) ->
   (MultiValue.T (Vector n a), MultiValue.T (Vector n a))
split_ :: forall n a. T (T n a) -> (T (Vector n a), T (Vector n a))
split_ (MultiValue.Cons (Repr n a
a,Repr n a
b)) = (Repr (Vector n a) -> T (Vector n a)
forall a. Repr a -> T a
MultiValue.Cons Repr (Vector n a)
Repr n a
a, Repr (Vector n a) -> T (Vector n a)
forall a. Repr a -> T a
MultiValue.Cons Repr (Vector n a)
Repr n a
b)

instance (TypeNum.Positive n, MultiVector.C a) => MultiValue.C (T n a) where
   type Repr (T n a) = (MultiVector.Repr n a, MultiVector.Repr n a)
   cons :: T n a -> T (T n a)
cons (Cons Vector n a
v0 Vector n a
v1) = T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge (Vector n a -> T n a
forall a n. (C a, Positive n) => Vector n a -> T n a
forall n. Positive n => Vector n a -> T n a
MultiVector.cons Vector n a
v0) (Vector n a -> T n a
forall a n. (C a, Positive n) => Vector n a -> T n a
forall n. Positive n => Vector n a -> T n a
MultiVector.cons Vector n a
v1)
   undef :: T (T n a)
undef = T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge T n a
forall a n. (C a, Positive n) => T n a
forall n. Positive n => T n a
MultiVector.undef T n a
forall a n. (C a, Positive n) => T n a
forall n. Positive n => T n a
MultiVector.undef
   zero :: T (T n a)
zero = T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge T n a
forall a n. (C a, Positive n) => T n a
forall n. Positive n => T n a
MultiVector.zero T n a
forall a n. (C a, Positive n) => T n a
forall n. Positive n => T n a
MultiVector.zero
   phi :: forall r. BasicBlock -> T (T n a) -> CodeGenFunction r (T (T n a))
phi BasicBlock
bb =
      ((T n a, T n a) -> T (T n a))
-> CodeGenFunction r (T n a, T n a)
-> CodeGenFunction r (T (T n a))
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T n a -> T n a -> T (T n a)) -> (T n a, T n a) -> T (T n a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge) (CodeGenFunction r (T n a, T n a) -> CodeGenFunction r (T (T n a)))
-> (T (T n a) -> CodeGenFunction r (T n a, T n a))
-> T (T n a)
-> CodeGenFunction r (T (T n a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      (T n a -> CodeGenFunction r (T n a),
 T n a -> CodeGenFunction r (T n a))
-> (T n a, T n a) -> CodeGenFunction r (T n a, T n a)
forall (f :: * -> *) a c b d.
Applicative f =>
(a -> f c, b -> f d) -> (a, b) -> f (c, d)
AppHT.mapPair (BasicBlock -> T n a -> CodeGenFunction r (T n a)
forall a n r.
(C a, Positive n) =>
BasicBlock -> T n a -> CodeGenFunction r (T n a)
forall n r.
Positive n =>
BasicBlock -> T n a -> CodeGenFunction r (T n a)
MultiVector.phi BasicBlock
bb, BasicBlock -> T n a -> CodeGenFunction r (T n a)
forall a n r.
(C a, Positive n) =>
BasicBlock -> T n a -> CodeGenFunction r (T n a)
forall n r.
Positive n =>
BasicBlock -> T n a -> CodeGenFunction r (T n a)
MultiVector.phi BasicBlock
bb) ((T n a, T n a) -> CodeGenFunction r (T n a, T n a))
-> (T (T n a) -> (T n a, T n a))
-> T (T n a)
-> CodeGenFunction r (T n a, T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (T n a) -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split
   addPhi :: forall r.
BasicBlock -> T (T n a) -> T (T n a) -> CodeGenFunction r ()
addPhi BasicBlock
bb T (T n a)
a T (T n a)
b =
      case (T (T n a) -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split T (T n a)
a, T (T n a) -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split T (T n a)
b) of
         ((T n a
a0,T n a
a1), (T n a
b0,T n a
b1)) -> do
            BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
forall a n r.
(C a, Positive n) =>
BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
forall n r.
Positive n =>
BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
MultiVector.addPhi BasicBlock
bb T n a
a0 T n a
b0
            BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
forall a n r.
(C a, Positive n) =>
BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
forall n r.
Positive n =>
BasicBlock -> T n a -> T n a -> CodeGenFunction r ()
MultiVector.addPhi BasicBlock
bb T n a
a1 T n a
b1

instance (Marshal.Vector n a) => Marshal.C (T n a) where
   pack :: T n a -> Struct (T n a)
pack (Cons Vector n a
v0 Vector n a
v1) = (Vector n a, Vector n a) -> Struct (Vector n a, Vector n a)
forall a. C a => a -> Struct a
Marshal.pack (Vector n a
v0,Vector n a
v1)
   unpack :: Struct (T n a) -> T n a
unpack = (Vector n a -> Vector n a -> T n a)
-> (Vector n a, Vector n a) -> T n a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Vector n a -> Vector n a -> T n a
forall n a. Vector n a -> Vector n a -> T n a
Cons ((Vector n a, Vector n a) -> T n a)
-> (Struct (Struct (Repr n a), (Struct (Repr n a), ()))
    -> (Vector n a, Vector n a))
-> Struct (Struct (Repr n a), (Struct (Repr n a), ()))
-> T n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Struct (Vector n a, Vector n a) -> (Vector n a, Vector n a)
Struct (Struct (Repr n a), (Struct (Repr n a), ()))
-> (Vector n a, Vector n a)
forall a. C a => Struct a -> a
Marshal.unpack

instance
   (TypeNum.Positive n, MultiVector.C a, St.Storable a) =>
      St.Storable (T n a) where
   sizeOf :: T n a -> Int
sizeOf ~(Cons Vector n a
v0 Vector n a
v1) = Vector n a -> Int
forall a. Storable a => a -> Int
St.sizeOf Vector n a
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Vector n a -> Int
forall a. Storable a => a -> Int
St.sizeOf Vector n a
v1
   alignment :: T n a -> Int
alignment ~(Cons Vector n a
v Vector n a
_) = Vector n a -> Int
forall a. Storable a => a -> Int
St.alignment Vector n a
v
   peek :: Ptr (T n a) -> IO (T n a)
peek Ptr (T n a)
ptr =
      let p :: Ptr (Vector n a)
p = Ptr (T n a) -> Ptr (Vector n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (T n a)
ptr
      in  (Vector n a -> Vector n a -> T n a)
-> IO (Vector n a) -> IO (Vector n a) -> IO (T n a)
forall a b c. (a -> b -> c) -> IO a -> IO b -> IO c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Vector n a -> Vector n a -> T n a
forall n a. Vector n a -> Vector n a -> T n a
Cons
             (Ptr (Vector n a) -> Int -> IO (Vector n a)
forall a. Storable a => Ptr a -> Int -> IO a
St.peekElemOff Ptr (Vector n a)
p Int
0)
             (Ptr (Vector n a) -> Int -> IO (Vector n a)
forall a. Storable a => Ptr a -> Int -> IO a
St.peekElemOff Ptr (Vector n a)
p Int
1)
   poke :: Ptr (T n a) -> T n a -> IO ()
poke Ptr (T n a)
ptr (Cons Vector n a
v0 Vector n a
v1) =
      let p :: Ptr (Vector n a)
p = Ptr (T n a) -> Ptr (Vector n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (T n a)
ptr
      in  Ptr (Vector n a) -> Int -> Vector n a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
St.pokeElemOff Ptr (Vector n a)
p Int
0 Vector n a
v0 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
          Ptr (Vector n a) -> Int -> Vector n a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
St.pokeElemOff Ptr (Vector n a)
p Int
1 Vector n a
v1

instance (TypeNum.Positive n, Storable.Vector a) => Storable.C (T n a) where
   load :: forall r. Value (Ptr (T n a)) -> CodeGenFunction r (T (T n a))
load Value (Ptr (T n a))
ptrV = do
      Value (Ptr (Vector n a))
ptr <- Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
forall n a r.
Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
castHalfPtr Value (Ptr (T n a))
ptrV
      (T (Vector n a) -> T (Vector n a) -> T (T n a))
-> CodeGenFunction r (T (Vector n a))
-> CodeGenFunction r (T (Vector n a))
-> CodeGenFunction r (T (T n a))
forall a b c.
(a -> b -> c)
-> CodeGenFunction r a
-> CodeGenFunction r b
-> CodeGenFunction r c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 T (Vector n a) -> T (Vector n a) -> T (T n a)
forall n a. T (Vector n a) -> T (Vector n a) -> T (T n a)
merge_
         (Value (Ptr (Vector n a)) -> CodeGenFunction r (T (Vector n a))
forall a r. C a => Value (Ptr a) -> CodeGenFunction r (T a)
forall r.
Value (Ptr (Vector n a)) -> CodeGenFunction r (T (Vector n a))
Storable.load Value (Ptr (Vector n a))
ptr)
         (Value (Ptr (Vector n a)) -> CodeGenFunction r (T (Vector n a))
forall a r. C a => Value (Ptr a) -> CodeGenFunction r (T a)
forall r.
Value (Ptr (Vector n a)) -> CodeGenFunction r (T (Vector n a))
Storable.load (Value (Ptr (Vector n a)) -> CodeGenFunction r (T (Vector n a)))
-> CodeGenFunction r (Value (Ptr (Vector n a)))
-> CodeGenFunction r (T (Vector n a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value (Ptr (Vector n a))
-> CodeGenFunction r (Value (Ptr (Vector n a)))
forall a ptr r.
(Storable a, Value (Ptr a) ~ ptr) =>
ptr -> CodeGenFunction r ptr
Storable.incrementPtr Value (Ptr (Vector n a))
ptr)
   store :: forall r. T (T n a) -> Value (Ptr (T n a)) -> CodeGenFunction r ()
store T (T n a)
v Value (Ptr (T n a))
ptrV = do
      let (T (Vector n a)
v0,T (Vector n a)
v1) = T (T n a) -> (T (Vector n a), T (Vector n a))
forall n a. T (T n a) -> (T (Vector n a), T (Vector n a))
split_ T (T n a)
v
      Value (Ptr (Vector n a))
ptr <- Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
forall n a r.
Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
castHalfPtr Value (Ptr (T n a))
ptrV
      T (Vector n a)
-> Value (Ptr (Vector n a))
-> CodeGenFunction r (Value (Ptr (Vector n a)))
forall a ptr r.
(C a, Value (Ptr a) ~ ptr) =>
T a -> ptr -> CodeGenFunction r ptr
Storable.storeNext T (Vector n a)
v0 Value (Ptr (Vector n a))
ptr CodeGenFunction r (Value (Ptr (Vector n a)))
-> (Value (Ptr (Vector n a)) -> CodeGenFunction r ())
-> CodeGenFunction r ()
forall a b.
CodeGenFunction r a
-> (a -> CodeGenFunction r b) -> CodeGenFunction r b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= T (Vector n a) -> Value (Ptr (Vector n a)) -> CodeGenFunction r ()
forall r.
T (Vector n a) -> Value (Ptr (Vector n a)) -> CodeGenFunction r ()
forall a r. C a => T a -> Value (Ptr a) -> CodeGenFunction r ()
Storable.store T (Vector n a)
v1

castHalfPtr ::
   LLVM.Value (Ptr (T n a)) ->
   LLVM.CodeGenFunction r (LLVM.Value (Ptr (Vector n a)))
castHalfPtr :: forall n a r.
Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
castHalfPtr = Value (Ptr (T n a)) -> CodeGenFunction r (Value (Ptr (Vector n a)))
forall (value :: * -> *) a b r.
(ValueCons value, IsSized a, IsSized b, SizeOf a ~ SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.bitcast


{- |
This instance allows to run @arrange@ on interleaved stereo vectors.
-}
instance
   (TypeNum.Positive n, MultiVector.Additive a) =>
      MultiValue.Additive (T n a) where
   add :: forall r. T (T n a) -> T (T n a) -> CodeGenFunction r (T (T n a))
add = (T n a -> T n a -> T (T n a))
-> (T n a -> T n a -> CodeGenFunction r (T n a))
-> T (T n a)
-> T (T n a)
-> CodeGenFunction r (T (T n a))
forall (m :: * -> *) c d n a b.
Applicative m =>
(c -> c -> d)
-> (T n a -> T n b -> m c) -> Value n a -> Value n b -> m d
zipV T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge T n a -> T n a -> CodeGenFunction r (T n a)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r. T n a -> T n a -> CodeGenFunction r (T n a)
A.add
   sub :: forall r. T (T n a) -> T (T n a) -> CodeGenFunction r (T (T n a))
sub = (T n a -> T n a -> T (T n a))
-> (T n a -> T n a -> CodeGenFunction r (T n a))
-> T (T n a)
-> T (T n a)
-> CodeGenFunction r (T (T n a))
forall (m :: * -> *) c d n a b.
Applicative m =>
(c -> c -> d)
-> (T n a -> T n b -> m c) -> Value n a -> Value n b -> m d
zipV T n a -> T n a -> T (T n a)
forall n a. T n a -> T n a -> T (T n a)
merge T n a -> T n a -> CodeGenFunction r (T n a)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r. T n a -> T n a -> CodeGenFunction r (T n a)
A.sub
   neg :: forall r. T (T n a) -> CodeGenFunction r (T (T n a))
neg = (T n a -> CodeGenFunction r (T n a))
-> T (T n a) -> CodeGenFunction r (T (T n a))
forall (m :: * -> *) n a.
Applicative m =>
(T n a -> m (T n a)) -> Value n a -> m (Value n a)
mapV T n a -> CodeGenFunction r (T n a)
forall a r. Additive a => a -> CodeGenFunction r a
forall r. T n a -> CodeGenFunction r (T n a)
A.neg


zero :: (TypeNum.Positive n, Additive.C a) => T n a
zero :: forall n a. (Positive n, C a) => T n a
zero = Vector n a -> Vector n a -> T n a
forall n a. Vector n a -> Vector n a -> T n a
Cons (a -> Vector n a
forall a. a -> Vector n a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. C a => a
Additive.zero) (a -> Vector n a
forall a. a -> Vector n a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. C a => a
Additive.zero)


scale ::
   (TypeNum.Positive n, MultiVector.PseudoRing a) =>
   MultiValue.T a -> Value n a -> LLVM.CodeGenFunction r (Value n a)
scale :: forall n a r.
(Positive n, PseudoRing a) =>
T a -> Value n a -> CodeGenFunction r (Value n a)
scale T a
a Value n a
v = do
   T n a
av <- T a -> CodeGenFunction r (T n a)
forall n a r. (Positive n, C a) => T a -> CodeGenFunction r (T n a)
MultiVector.replicate T a
a
   (T n a -> CodeGenFunction r (T n a))
-> Value n a -> CodeGenFunction r (Value n a)
forall (m :: * -> *) n a.
Applicative m =>
(T n a -> m (T n a)) -> Value n a -> m (Value n a)
mapV (T n a -> T n a -> CodeGenFunction r (T n a)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r. T n a -> T n a -> CodeGenFunction r (T n a)
A.mul T n a
av) Value n a
v

amplify ::
   (TypeNum.Positive n, MultiVector.PseudoRing a) =>
   a -> Value n a -> LLVM.CodeGenFunction r (Value n a)
amplify :: forall n a r.
(Positive n, PseudoRing a) =>
a -> Value n a -> CodeGenFunction r (Value n a)
amplify a
a = T a -> Value n a -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, PseudoRing a) =>
T a -> Value n a -> CodeGenFunction r (Value n a)
scale (a -> T a
forall a. C a => a -> T a
MultiValue.cons a
a)

envelope ::
   (TypeNum.Positive n, MultiVector.PseudoRing a) =>
   Serial.Value n a -> Value n a -> LLVM.CodeGenFunction r (Value n a)
envelope :: forall n a r.
(Positive n, PseudoRing a) =>
Value n a -> Value n a -> CodeGenFunction r (Value n a)
envelope Value n a
e Value n a
a =
   (T n a -> T n a -> Value n a)
-> (T n a -> T n a -> CodeGenFunction r (T n a))
-> Value n a
-> Value n a
-> CodeGenFunction r (Value n a)
forall (m :: * -> *) c d n a b.
Applicative m =>
(c -> c -> d)
-> (T n a -> T n b -> m c) -> Value n a -> Value n b -> m d
zipV T n a -> T n a -> Value n a
forall n a. T n a -> T n a -> T (T n a)
merge ((T n a -> T n a -> CodeGenFunction r (T n a))
-> T n a -> T n a -> CodeGenFunction r (T n a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip T n a -> T n a -> CodeGenFunction r (T n a)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r. T n a -> T n a -> CodeGenFunction r (T n a)
A.mul) Value n a
a (Value n a -> CodeGenFunction r (Value n a))
-> CodeGenFunction r (Value n a) -> CodeGenFunction r (Value n a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value n a -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r (Value n a)
fromMono Value n a
e


mapV :: (Applicative m) =>
   (MultiVector.T n a -> m (MultiVector.T n a)) ->
   Value n a -> m (Value n a)
mapV :: forall (m :: * -> *) n a.
Applicative m =>
(T n a -> m (T n a)) -> Value n a -> m (Value n a)
mapV T n a -> m (T n a)
f Value n a
x =
   case Value n a -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split Value n a
x of
      (T n a
x0,T n a
x1) -> (T n a -> T n a -> Value n a) -> (T n a, T n a) -> Value n a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T n a -> T n a -> Value n a
forall n a. T n a -> T n a -> T (T n a)
merge ((T n a, T n a) -> Value n a) -> m (T n a, T n a) -> m (Value n a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (T n a -> T n a -> (T n a, T n a))
-> m (T n a) -> m (T n a) -> m (T n a, T n a)
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (T n a -> m (T n a)
f T n a
x0) (T n a -> m (T n a)
f T n a
x1)

zipV :: (Applicative m) =>
   (c -> c -> d) ->
   (MultiVector.T n a ->
    MultiVector.T n b ->
    m c) ->
   Value n a ->
   Value n b ->
   m d
zipV :: forall (m :: * -> *) c d n a b.
Applicative m =>
(c -> c -> d)
-> (T n a -> T n b -> m c) -> Value n a -> Value n b -> m d
zipV c -> c -> d
g T n a -> T n b -> m c
f Value n a
x Value n b
y =
   case (Value n a -> (T n a, T n a)
forall n a. T (T n a) -> (T n a, T n a)
split Value n a
x, Value n b -> (T n b, T n b)
forall n a. T (T n a) -> (T n a, T n a)
split Value n b
y) of
      ((T n a
x0,T n a
x1), (T n b
y0,T n b
y1)) -> (c -> c -> d) -> m c -> m c -> m d
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 c -> c -> d
g (T n a -> T n b -> m c
f T n a
x0 T n b
y0) (T n a -> T n b -> m c
f T n a
x1 T n b
y1)