{-# LANGUAGE TypeFamilies #-}
{- |
Apply operations on symbolic arrays to physical ones.
-}
module Data.Array.Knead.Symbolic.Render (
   run,
   MarshalExp(..),
   MapFilter(..),
   FilterOuter(..),
   Scatter(..),
   ScatterMaybe(..),
   MapAccumLSimple(..),
   MapAccumLSequence(..),
   MapAccumL(..),
   FoldOuterL(..),
   AddDimension(..),
   ) where

import qualified Data.Array.Knead.Symbolic.Render.Basic as Render
import qualified Data.Array.Knead.Symbolic.Render.Argument as Arg
import qualified Data.Array.Knead.Symbolic.PhysicalParametric as PhysP
import qualified Data.Array.Knead.Symbolic.Physical as Phys
import qualified Data.Array.Knead.Symbolic.Private as Core
import qualified Data.Array.Knead.Shape as Shape
import Data.Array.Knead.Symbolic.PhysicalParametric
         (MapFilter, FilterOuter,
          MapAccumLSimple, MapAccumLSequence, MapAccumL, FoldOuterL,
          Scatter, ScatterMaybe, AddDimension)

import qualified LLVM.DSL.Render.Run as Run
import LLVM.DSL.Expression (Exp)

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 Prelude2010
import Prelude ()



class C f where
   type Plain f
   function :: (Marshal.C p) => Run.T IO p f (Plain f)

instance
   (Marshal.C sh, Shape.C sh, Storable.C a) =>
      C (Core.Array sh a) where
   type Plain (Core.Array sh a) = IO (Phys.Array sh a)
   function :: forall p. C p => T IO p (Array sh a) (Plain (Array sh a))
function = ((Exp p -> Array sh a) -> IO (Creator p -> IO (Array sh a)))
-> T IO p (Array sh a) (IO (Array sh a))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> Array sh a) -> IO (Creator p -> IO (Array sh a))
forall sh ix p a.
(C sh, Index sh ~ ix, C sh, C p, C a) =>
Parametric p (Array sh a) -> IO (Rendered p (Array sh a))
PhysP.render

instance
   (Shape.Sequence n, Marshal.C n,
    Storable.C b, MultiValue.C b) =>
      C (MapFilter n a b) where
   type Plain (MapFilter n a b) = IO (Phys.Array n b)
   function :: forall p. C p => T IO p (MapFilter n a b) (Plain (MapFilter n a b))
function = ((Exp p -> MapFilter n a b) -> IO (Creator p -> IO (Array n b)))
-> T IO p (MapFilter n a b) (IO (Array n b))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> MapFilter n a b) -> IO (Creator p -> IO (Array n b))
forall n p b a.
(Sequence n, C n, C p, C b) =>
Parametric p (MapFilter n a b) -> IO (Rendered p (Array n b))
PhysP.mapFilter

instance
   (Shape.Sequence n, Marshal.C n,
    Shape.C sh, Marshal.C sh,
    Storable.C a, MultiValue.C a) =>
      C (FilterOuter n sh a) where
   type Plain (FilterOuter n sh a) = IO (Phys.Array (n,sh) a)
   function :: forall p.
C p =>
T IO p (FilterOuter n sh a) (Plain (FilterOuter n sh a))
function = ((Exp p -> FilterOuter n sh a)
 -> IO (Creator p -> IO (Array (n, sh) a)))
-> T IO p (FilterOuter n sh a) (IO (Array (n, sh) a))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> FilterOuter n sh a)
-> IO (Creator p -> IO (Array (n, sh) a))
forall n sh p a.
(Sequence n, C n, C sh, C sh, C p, C a) =>
Parametric p (FilterOuter n sh a)
-> IO (Rendered p (Array (n, sh) a))
PhysP.filterOuter

instance
   (Shape.C sh0, Marshal.C sh0,
    Shape.C sh1, Marshal.C sh1,
    Storable.C a, MultiValue.C a) =>
      C (Scatter sh0 sh1 a) where
   type Plain (Scatter sh0 sh1 a) = IO (Phys.Array sh1 a)
   function :: forall p.
C p =>
T IO p (Scatter sh0 sh1 a) (Plain (Scatter sh0 sh1 a))
function = ((Exp p -> Scatter sh0 sh1 a)
 -> IO (Creator p -> IO (Array sh1 a)))
-> T IO p (Scatter sh0 sh1 a) (IO (Array sh1 a))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> Scatter sh0 sh1 a) -> IO (Creator p -> IO (Array sh1 a))
forall sh0 ix0 sh1 ix1 p a.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C p,
 C a) =>
Parametric p (Scatter sh0 sh1 a) -> IO (Rendered p (Array sh1 a))
PhysP.scatter

instance
   (Shape.C sh0, Marshal.C sh0,
    Shape.C sh1, Marshal.C sh1,
    Storable.C a, MultiValue.C a) =>
      C (ScatterMaybe sh0 sh1 a) where
   type Plain (ScatterMaybe sh0 sh1 a) = IO (Phys.Array sh1 a)
   function :: forall p.
C p =>
T IO p (ScatterMaybe sh0 sh1 a) (Plain (ScatterMaybe sh0 sh1 a))
function = ((Exp p -> ScatterMaybe sh0 sh1 a)
 -> IO (Creator p -> IO (Array sh1 a)))
-> T IO p (ScatterMaybe sh0 sh1 a) (IO (Array sh1 a))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> ScatterMaybe sh0 sh1 a)
-> IO (Creator p -> IO (Array sh1 a))
forall sh0 ix0 sh1 ix1 p a.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C p,
 C a) =>
Parametric p (ScatterMaybe sh0 sh1 a)
-> IO (Rendered p (Array sh1 a))
PhysP.scatterMaybe

instance
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    MultiValue.C acc,
    Storable.C a, MultiValue.C a,
    Storable.C b, MultiValue.C b) =>
      C (MapAccumLSimple sh n acc a b) where
   type Plain (MapAccumLSimple sh n acc a b) = IO (Phys.Array (sh,n) b)
   function :: forall p.
C p =>
T IO
  p
  (MapAccumLSimple sh n acc a b)
  (Plain (MapAccumLSimple sh n acc a b))
function = ((Exp p -> MapAccumLSimple sh n acc a b)
 -> IO (Creator p -> IO (Array (sh, n) b)))
-> T IO p (MapAccumLSimple sh n acc a b) (IO (Array (sh, n) b))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> MapAccumLSimple sh n acc a b)
-> IO (Creator p -> IO (Array (sh, n) b))
forall sh n acc p a b.
(C sh, C sh, C n, C n, C acc, C p, C a, C b) =>
Parametric p (MapAccumLSimple sh n acc a b)
-> IO (Rendered p (Array (sh, n) b))
PhysP.mapAccumLSimple

instance
   (Shape.C n, Marshal.C n,
    MultiValue.C acc,
    Storable.C final, MultiValue.C final,
    Storable.C a, MultiValue.C a,
    Storable.C b, MultiValue.C b) =>
      C (MapAccumLSequence n acc final a b) where
   type Plain (MapAccumLSequence n acc final a b) = IO (final, Phys.Array n b)
   function :: forall p.
C p =>
T IO
  p
  (MapAccumLSequence n acc final a b)
  (Plain (MapAccumLSequence n acc final a b))
function = ((Exp p -> MapAccumLSequence n acc final a b)
 -> IO (Creator p -> IO (final, Array n b)))
-> T IO
     p
     (MapAccumLSequence n acc final a b)
     (IO (final, Array n b))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> MapAccumLSequence n acc final a b)
-> IO (Creator p -> IO (final, Array n b))
forall n acc final p a b.
(C n, C n, C acc, C final, C p, C a, C b) =>
Parametric p (MapAccumLSequence n acc final a b)
-> IO (Rendered p (final, Array n b))
PhysP.mapAccumLSequence

instance
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    MultiValue.C acc,
    Storable.C final, MultiValue.C final,
    Storable.C a, MultiValue.C a,
    Storable.C b, MultiValue.C b) =>
      C (MapAccumL sh n acc final a b) where
   type Plain (MapAccumL sh n acc final a b) =
            IO (Phys.Array sh final, Phys.Array (sh,n) b)
   function :: forall p.
C p =>
T IO
  p
  (MapAccumL sh n acc final a b)
  (Plain (MapAccumL sh n acc final a b))
function = ((Exp p -> MapAccumL sh n acc final a b)
 -> IO (Creator p -> IO (Array sh final, Array (sh, n) b)))
-> T IO
     p
     (MapAccumL sh n acc final a b)
     (IO (Array sh final, Array (sh, n) b))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> MapAccumL sh n acc final a b)
-> IO (Creator p -> IO (Array sh final, Array (sh, n) b))
forall sh n acc final p a b.
(C sh, C sh, C n, C n, C acc, C final, C p, C a, C b) =>
Parametric p (MapAccumL sh n acc final a b)
-> IO (Rendered p (Array sh final, Array (sh, n) b))
PhysP.mapAccumL

instance
   (Shape.C n, Marshal.C n,
    Shape.C sh, Marshal.C sh,
    Storable.C a, MultiValue.C a,
    Storable.C b, MultiValue.C b) =>
      C (FoldOuterL n sh a b) where
   type Plain (FoldOuterL n sh a b) = IO (Phys.Array sh a)
   function :: forall p.
C p =>
T IO p (FoldOuterL n sh a b) (Plain (FoldOuterL n sh a b))
function = ((Exp p -> FoldOuterL n sh a b)
 -> IO (Creator p -> IO (Array sh a)))
-> T IO p (FoldOuterL n sh a b) (IO (Array sh a))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> FoldOuterL n sh a b) -> IO (Creator p -> IO (Array sh a))
forall n sh p a b.
(C n, C n, C sh, C sh, C p, C a) =>
Parametric p (FoldOuterL n sh a b) -> IO (Rendered p (Array sh a))
PhysP.foldOuterL

instance
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    Storable.C b, MultiValue.C b) =>
      C (AddDimension sh n a b) where
   type Plain (AddDimension sh n a b) = IO (Phys.Array (sh,n) b)
   function :: forall p.
C p =>
T IO p (AddDimension sh n a b) (Plain (AddDimension sh n a b))
function = ((Exp p -> AddDimension sh n a b)
 -> IO (Creator p -> IO (Array (sh, n) b)))
-> T IO p (AddDimension sh n a b) (IO (Array (sh, n) b))
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (Exp p -> AddDimension sh n a b)
-> IO (Creator p -> IO (Array (sh, n) b))
forall sh n p b a.
(C sh, C sh, C n, C n, C p, C b) =>
Parametric p (AddDimension sh n a b)
-> IO (Rendered p (Array (sh, n) b))
PhysP.addDimension


instance (Storable.C a, MultiValue.C a) => C (Exp a) where
   type Plain (Exp a) = IO a
   function :: forall p. C p => T IO p (Exp a) (Plain (Exp a))
function = T IO p (Exp a) (IO a)
T IO p (Exp a) (Plain (Exp a))
forall p a. (C p, C a) => T IO p (Exp a) (IO a)
Render.storable

newtype MarshalExp a = MarshalExp {forall a. MarshalExp a -> Exp a
getMarshalExp :: Exp a}

instance (Marshal.C a) => C (MarshalExp a) where
   type Plain (MarshalExp a) = IO a
   function :: forall p. C p => T IO p (MarshalExp a) (Plain (MarshalExp a))
function = (MarshalExp a -> Exp a)
-> T IO p (Exp a) (IO a) -> T IO p (MarshalExp a) (IO a)
forall gdsl fdsl (m :: * -> *) p f.
(gdsl -> fdsl) -> T m p fdsl f -> T m p gdsl f
Run.premapDSL MarshalExp a -> Exp a
forall a. MarshalExp a -> Exp a
getMarshalExp T IO p (Exp a) (IO a)
forall p a. (C p, C a) => T IO p (Exp a) (IO a)
Render.marshal

instance (Argument arg, C func) => C (arg -> func) where
   type Plain (arg -> func) = PlainArg arg -> Plain func
   function :: forall p. C p => T IO p (arg -> func) (Plain (arg -> func))
function = T (PlainArg arg) arg
forall a. Argument a => T (PlainArg a) a
argument T (PlainArg arg) arg
-> (forall al. C al => T IO (p, al) func (Plain func))
-> T IO p (arg -> func) (PlainArg arg -> Plain func)
forall (m :: * -> *) a adsl p fdsl f.
Functor m =>
T a adsl
-> (forall al. C al => T m (p, al) fdsl f)
-> T m p (adsl -> fdsl) (a -> f)
Render.*-> T IO (p, al) func (Plain func)
forall p. C p => T IO p func (Plain func)
forall al. C al => T IO (p, al) func (Plain func)
forall f p. (C f, C p) => T IO p f (Plain f)
function


class Argument a where
   type PlainArg a
   argument :: Arg.T (PlainArg a) a

instance Argument () where
   type PlainArg () = ()
   argument :: T (PlainArg ()) ()
argument = T () ()
T (PlainArg ()) ()
Arg.unit

instance
   (Shape.C sh, Marshal.C sh, Storable.C a) =>
      Argument (Core.Array sh a) where
   type PlainArg (Core.Array sh a) = Phys.Array sh a
   argument :: T (PlainArg (Array sh a)) (Array sh a)
argument = T (Array sh a) (Array sh a)
T (PlainArg (Array sh a)) (Array sh a)
forall sh a. (C sh, C sh, C a) => T (Array sh a) (Array sh a)
Arg.array

instance (Marshal.C a) => Argument (Exp a) where
   type PlainArg (Exp a) = a
   argument :: T (PlainArg (Exp a)) (Exp a)
argument = T a (Exp a)
T (PlainArg (Exp a)) (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive

instance (Argument a, Argument b) => Argument (a,b) where
   type PlainArg (a,b) = (PlainArg a, PlainArg b)
   argument :: T (PlainArg (a, b)) (a, b)
argument = T (PlainArg a) a
-> T (PlainArg b) b -> T (PlainArg a, PlainArg b) (a, b)
forall a ad b bd. T a ad -> T b bd -> T (a, b) (ad, bd)
Arg.pair T (PlainArg a) a
forall a. Argument a => T (PlainArg a) a
argument T (PlainArg b) b
forall a. Argument a => T (PlainArg a) a
argument

instance (Argument a, Argument b, Argument c) => Argument (a,b,c) where
   type PlainArg (a,b,c) = (PlainArg a, PlainArg b, PlainArg c)
   argument :: T (PlainArg (a, b, c)) (a, b, c)
argument = T (PlainArg a) a
-> T (PlainArg b) b
-> T (PlainArg c) c
-> T (PlainArg a, PlainArg b, PlainArg c) (a, b, c)
forall a ad b bd c cd.
T a ad -> T b bd -> T c cd -> T (a, b, c) (ad, bd, cd)
Arg.triple T (PlainArg a) a
forall a. Argument a => T (PlainArg a) a
argument T (PlainArg b) b
forall a. Argument a => T (PlainArg a) a
argument T (PlainArg c) c
forall a. Argument a => T (PlainArg a) a
argument



run :: (C f) => f -> IO (Plain f)
run :: forall f. C f => f -> IO (Plain f)
run = T IO () f (Plain f) -> f -> IO (Plain f)
forall (m :: * -> *) fdsl f.
Functor m =>
T m () fdsl f -> fdsl -> m f
Render.run T IO () f (Plain f)
forall p. C p => T IO p f (Plain f)
forall f p. (C f, C p) => T IO p f (Plain f)
function