{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{- |
A special vector type that represents a time-sequence of samples.
This way we can distinguish safely between LLVM vectors
used for parallel signals and pipelines and
those used for chunky processing of scalar signals.
For the chunky processing this data type allows us
to derive the factor from the type
that time constants have to be multiplied with.
-}
module Synthesizer.LLVM.Frame.SerialVector (
   T(Cons),
   fromFixedList,
   upsample, subsample,
   shiftUp,
   reverse, iterate, cumulate,
   limit,
   select, cmp,
   ) where

import qualified Synthesizer.LLVM.Frame.SerialVector.Code as Code
import Synthesizer.LLVM.Frame.SerialVector.Code
         (T, fromMultiVector, toMultiVector)

import qualified LLVM.DSL.Expression.Vector as ExprVec
import qualified LLVM.DSL.Expression as Expr
import LLVM.DSL.Expression (Exp)

import qualified LLVM.Extra.Multi.Vector as MultiVector
import qualified LLVM.Extra.Multi.Value.Vector as MultiValueVec
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Arithmetic as A

import qualified LLVM.Core as LLVM

import qualified Type.Data.Num.Decimal as TypeNum

import Data.Word (Word32)

import Prelude hiding (replicate, reverse, iterate)


fromFixedList ::
   (TypeNum.Positive n, MultiVector.C a) =>
   LLVM.FixedList (TypeNum.ToUnary n) a -> Exp (T n a)
fromFixedList :: forall n a.
(Positive n, C a) =>
FixedList (ToUnary n) a -> Exp (T n a)
fromFixedList = Exp (Vector n a) -> Exp (T n a)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n a) -> Exp (T n a))
-> (List (ToUnary n) a -> Exp (Vector n a))
-> List (ToUnary n) a
-> Exp (T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector n a -> Exp (Vector n a)
forall a. C a => a -> Exp a
Expr.cons (Vector n a -> Exp (Vector n a))
-> (List (ToUnary n) a -> Vector n a)
-> List (ToUnary n) a
-> Exp (Vector n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. List (ToUnary n) a -> Vector n a
forall n a. Positive n => FixedList (ToUnary n) a -> Vector n a
LLVM.vector



subsample :: (TypeNum.Positive n, MultiVector.C a) => Exp (T n a) -> Exp a
subsample :: forall n a. (Positive n, C a) => Exp (T n a) -> Exp a
subsample =
   (forall r. MVVector n a -> CodeGenFunction r (T a))
-> Exp (Vector n a) -> Exp a
forall ae am b.
Aggregate ae am =>
(forall r. am -> CodeGenFunction r (T b)) -> ae -> Exp b
Expr.liftM (Value Word32 -> MVVector n a -> CodeGenFunction r (T a)
forall n a r.
(Positive n, C a) =>
Value Word32 -> MVVector n a -> CodeGenFunction r (T a)
MultiValueVec.extract (Value Word32
forall a. Additive a => a
A.zero :: LLVM.Value Word32)) (Exp (Vector n a) -> Exp a)
-> (Exp (T n a) -> Exp (Vector n a)) -> Exp (T n a) -> Exp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary

upsample :: (TypeNum.Positive n, MultiVector.C a) => Exp a -> Exp (T n a)
upsample :: forall n a. (Positive n, C a) => Exp a -> Exp (T n a)
upsample = Exp (Vector n a) -> Exp (T n a)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n a) -> Exp (T n a))
-> (Exp a -> Exp (Vector n a)) -> Exp a -> Exp (T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp a -> Exp (Vector n a)
forall n a. (Positive n, C a) => Exp a -> Exp (Vector n a)
ExprVec.replicate


shiftUp ::
   (TypeNum.Positive n, MultiVector.C x, Exp x ~ a, Exp (T n x) ~ v) =>
   a -> v -> (a, v)
shiftUp :: forall n x a v.
(Positive n, C x, Exp x ~ a, Exp (T n x) ~ v) =>
a -> v -> (a, v)
shiftUp a
a v
v =
   ((forall r. T x -> Value n x -> CodeGenFunction r (T x))
-> a -> v -> Exp x
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 ((((T x, Value n x) -> T x)
-> CodeGenFunction r (T x, Value n x) -> CodeGenFunction r (T x)
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 x, Value n x) -> T x
forall a b. (a, b) -> a
fst (CodeGenFunction r (T x, Value n x) -> CodeGenFunction r (T x))
-> (Value n x -> CodeGenFunction r (T x, Value n x))
-> Value n x
-> CodeGenFunction r (T x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Value n x -> CodeGenFunction r (T x, Value n x))
 -> Value n x -> CodeGenFunction r (T x))
-> (T x -> Value n x -> CodeGenFunction r (T x, Value n x))
-> T x
-> Value n x
-> CodeGenFunction r (T x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T x -> Value n x -> CodeGenFunction r (T x, Value n x)
forall n x a v r.
(Positive n, C x, T x ~ a, Value n x ~ v) =>
a -> v -> CodeGenFunction r (a, v)
Code.shiftUp) a
a v
v,
    (forall r. T x -> Value n x -> CodeGenFunction r (Value n x))
-> a -> v -> Exp (T n x)
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 ((((T x, Value n x) -> Value n x)
-> CodeGenFunction r (T x, Value n x)
-> CodeGenFunction r (Value n x)
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 x, Value n x) -> Value n x
forall a b. (a, b) -> b
snd (CodeGenFunction r (T x, Value n x)
 -> CodeGenFunction r (Value n x))
-> (Value n x -> CodeGenFunction r (T x, Value n x))
-> Value n x
-> CodeGenFunction r (Value n x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Value n x -> CodeGenFunction r (T x, Value n x))
 -> Value n x -> CodeGenFunction r (Value n x))
-> (T x -> Value n x -> CodeGenFunction r (T x, Value n x))
-> T x
-> Value n x
-> CodeGenFunction r (Value n x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T x -> Value n x -> CodeGenFunction r (T x, Value n x)
forall n x a v r.
(Positive n, C x, T x ~ a, Value n x ~ v) =>
a -> v -> CodeGenFunction r (a, v)
Code.shiftUp) a
a v
v)


iterate ::
   (TypeNum.Positive n, MultiVector.C a) =>
   (Exp a -> Exp a) -> Exp a -> Exp (T n a)
iterate :: forall n a.
(Positive n, C a) =>
(Exp a -> Exp a) -> Exp a -> Exp (T n a)
iterate Exp a -> Exp a
f = Exp (Vector n a) -> Exp (T n a)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n a) -> Exp (T n a))
-> (Exp a -> Exp (Vector n a)) -> Exp a -> Exp (T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp a -> Exp a) -> Exp a -> Exp (Vector n a)
forall n a.
(Positive n, C a) =>
(Exp a -> Exp a) -> Exp a -> Exp (Vector n a)
ExprVec.iterate Exp a -> Exp a
f

reverse ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Exp (T n a) -> Exp (T n a)
reverse :: forall n a. (Positive n, C a) => Exp (T n a) -> Exp (T n a)
reverse =
   (forall r. Value n a -> CodeGenFunction r (Value n a))
-> Exp (T n a) -> Exp (T n a)
forall ae am b.
Aggregate ae am =>
(forall r. am -> CodeGenFunction r (T b)) -> ae -> Exp b
Expr.liftM ((T n a -> Value n a)
-> CodeGenFunction r (T n a) -> CodeGenFunction r (Value 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 -> Value n a
forall n a. T n a -> Value n a
fromMultiVector (CodeGenFunction r (T n a) -> CodeGenFunction r (Value n a))
-> (Value n a -> CodeGenFunction r (T n a))
-> Value n a
-> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T n a -> CodeGenFunction r (T n a)
forall n a r.
(Positive n, C a) =>
T n a -> CodeGenFunction r (T n a)
MultiVector.reverse (T n a -> CodeGenFunction r (T n a))
-> (Value n a -> T n a) -> Value n a -> CodeGenFunction r (T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value n a -> T n a
forall n a. Value n a -> T n a
toMultiVector)


cumulate ::
   (TypeNum.Positive n, MultiVector.Additive a) =>
   Exp a -> Exp (T n a) -> (Exp a, Exp (T n a))
cumulate :: forall n a.
(Positive n, Additive a) =>
Exp a -> Exp (T n a) -> (Exp a, Exp (T n a))
cumulate Exp a
a Exp (T n a)
v =
   ((forall r. T a -> Value n a -> CodeGenFunction r (T a))
-> Exp a -> Exp (T n a) -> Exp a
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 ((((T a, Value n a) -> T a)
-> CodeGenFunction r (T a, Value n a) -> CodeGenFunction r (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 (T a, Value n a) -> T a
forall a b. (a, b) -> a
fst (CodeGenFunction r (T a, Value n a) -> CodeGenFunction r (T a))
-> (Value n a -> CodeGenFunction r (T a, Value n a))
-> Value n a
-> CodeGenFunction r (T a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Value n a -> CodeGenFunction r (T a, Value n a))
 -> Value n a -> CodeGenFunction r (T a))
-> (T a -> Value n a -> CodeGenFunction r (T a, Value n a))
-> T a
-> Value n a
-> CodeGenFunction r (T a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> Value n a -> CodeGenFunction r (T a, Value n a)
forall n a r.
(Positive n, Additive a) =>
T a -> Value n a -> CodeGenFunction r (T a, Value n a)
Code.cumulate) Exp a
a Exp (T n a)
v,
    (forall r. T a -> Value n a -> CodeGenFunction r (Value n a))
-> Exp a -> Exp (T n a) -> Exp (T n a)
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 ((((T a, Value n a) -> Value n a)
-> CodeGenFunction r (T a, Value n a)
-> CodeGenFunction r (Value 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 a, Value n a) -> Value n a
forall a b. (a, b) -> b
snd (CodeGenFunction r (T a, Value n a)
 -> CodeGenFunction r (Value n a))
-> (Value n a -> CodeGenFunction r (T a, Value n a))
-> Value n a
-> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Value n a -> CodeGenFunction r (T a, Value n a))
 -> Value n a -> CodeGenFunction r (Value n a))
-> (T a -> Value n a -> CodeGenFunction r (T a, Value n a))
-> T a
-> Value n a
-> CodeGenFunction r (Value n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> Value n a -> CodeGenFunction r (T a, Value n a)
forall n a r.
(Positive n, Additive a) =>
T a -> Value n a -> CodeGenFunction r (T a, Value n a)
Code.cumulate) Exp a
a Exp (T n a)
v)

limit ::
   (TypeNum.Positive n, MultiVector.Real a) =>
   (Exp (T n a), Exp (T n a)) -> Exp (T n a) -> Exp (T n a)
limit :: forall n a.
(Positive n, Real a) =>
(Exp (T n a), Exp (T n a)) -> Exp (T n a) -> Exp (T n a)
limit (Exp (T n a)
l,Exp (T n a)
u) =
   Exp (Vector n a) -> Exp (T n a)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n a) -> Exp (T n a))
-> (Exp (T n a) -> Exp (Vector n a)) -> Exp (T n a) -> Exp (T n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp (Vector n a), Exp (Vector n a))
-> Exp (Vector n a) -> Exp (Vector n a)
forall n a.
(Positive n, Real a) =>
(Exp (Vector n a), Exp (Vector n a))
-> Exp (Vector n a) -> Exp (Vector n a)
ExprVec.limit (Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
l, Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
u) (Exp (Vector n a) -> Exp (Vector n a))
-> (Exp (T n a) -> Exp (Vector n a))
-> Exp (T n a)
-> Exp (Vector n a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary


cmp ::
   (TypeNum.Positive n, MultiVector.Comparison a) =>
   LLVM.CmpPredicate -> Exp (T n a) -> Exp (T n a) -> Exp (T n Bool)
cmp :: forall n a.
(Positive n, Comparison a) =>
CmpPredicate -> Exp (T n a) -> Exp (T n a) -> Exp (T n Bool)
cmp CmpPredicate
ord Exp (T n a)
a Exp (T n a)
b = Exp (Vector n Bool) -> Exp (T n Bool)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n Bool) -> Exp (T n Bool))
-> Exp (Vector n Bool) -> Exp (T n Bool)
forall a b. (a -> b) -> a -> b
$ CmpPredicate
-> Exp (Vector n a) -> Exp (Vector n a) -> Exp (Vector n Bool)
forall n a.
(Positive n, Comparison a) =>
CmpPredicate
-> Exp (Vector n a) -> Exp (Vector n a) -> Exp (Vector n Bool)
ExprVec.cmp CmpPredicate
ord (Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
a) (Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
b)

select ::
   (TypeNum.Positive n, MultiVector.Select a) =>
   Exp (T n Bool) -> Exp (T n a) -> Exp (T n a) -> Exp (T n a)
select :: forall n a.
(Positive n, Select a) =>
Exp (T n Bool) -> Exp (T n a) -> Exp (T n a) -> Exp (T n a)
select Exp (T n Bool)
c Exp (T n a)
a Exp (T n a)
b =
   Exp (Vector n a) -> Exp (T n a)
forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary (Exp (Vector n a) -> Exp (T n a))
-> Exp (Vector n a) -> Exp (T n a)
forall a b. (a -> b) -> a -> b
$ Exp (Vector n Bool)
-> Exp (Vector n a) -> Exp (Vector n a) -> Exp (Vector n a)
forall n a.
(Positive n, Select a) =>
Exp (Vector n Bool)
-> Exp (Vector n a) -> Exp (Vector n a) -> Exp (Vector n a)
ExprVec.select (Exp (T n Bool) -> Exp (Vector n Bool)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n Bool)
c) (Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
a) (Exp (T n a) -> Exp (Vector n a)
forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary Exp (T n a)
b)


fromOrdinary :: Exp (LLVM.Vector n a) -> Exp (T n a)
fromOrdinary :: forall n a. Exp (Vector n a) -> Exp (T n a)
fromOrdinary = (T (Vector n a) -> T (T n a)) -> Exp (Vector n a) -> Exp (T n a)
forall a b. (T a -> T b) -> Exp a -> Exp b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 T (Vector n a) -> T (T n a)
forall a b. (Repr a ~ Repr b) => T a -> T b
MultiValue.cast

toOrdinary :: Exp (T n a) -> Exp (LLVM.Vector n a)
toOrdinary :: forall n a. Exp (T n a) -> Exp (Vector n a)
toOrdinary = (T (T n a) -> T (Vector n a)) -> Exp (T n a) -> Exp (Vector n a)
forall a b. (T a -> T b) -> Exp a -> Exp b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 T (T n a) -> T (Vector n a)
forall a b. (Repr a ~ Repr b) => T a -> T b
MultiValue.cast