{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Rank2Types #-}
{- |
Apply operations on symbolic arrays to physical ones.

This is an approach with no pre-defined direction of type dependencies.
-}
module Data.Array.Knead.Symbolic.Render.Basic (
   run,
   (*->),

   storable,
   marshal,
   array,
   scatter,
   ) where

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 qualified Data.Array.Comfort.Storable.Unchecked as Array

import qualified LLVM.DSL.Render.Run as Run
import LLVM.DSL.Render.Run (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 Prelude2010
import Prelude ()



_example1raw ::
   (Marshal.C sh, Shape.C sh, Marshal.C z, Marshal.C a, Storable.C b) =>
   Run.T IO z (Exp a -> Core.Array sh b) (a -> IO (Phys.Array sh b))
_example1raw :: forall sh z a b.
(C sh, C sh, C z, C a, C b) =>
T IO z (Exp a -> Array sh b) (a -> IO (Array sh b))
_example1raw = T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al. C al => T IO (z, al) (Array sh b) (IO (Array sh b)))
-> T IO z (Exp a -> Array sh b) (a -> IO (Array sh b))
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)
*-> T IO (z, al) (Array sh b) (IO (Array sh b))
forall al. C al => T IO (z, al) (Array sh b) (IO (Array sh b))
forall sh ix p a.
(C sh, Index sh ~ ix, C sh, C p, C a) =>
T IO p (Array sh a) (IO (Array sh a))
array

_example2raw ::
   (Marshal.C sh, Shape.C sh,
    Marshal.C z, Marshal.C a, Marshal.C b, Storable.C c) =>
   Run.T IO z
      (Exp a -> Exp b -> Core.Array sh c)
      (a -> b -> IO (Phys.Array sh c))
_example2raw :: forall sh z a b c.
(C sh, C sh, C z, C a, C b, C c) =>
T IO z (Exp a -> Exp b -> Array sh c) (a -> b -> IO (Array sh c))
_example2raw = T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al.
    C al =>
    T IO (z, al) (Exp b -> Array sh c) (b -> IO (Array sh c)))
-> T IO
     z
     (Exp a -> Exp b -> Array sh c)
     (a -> b -> IO (Array sh c))
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)
*-> T b (Exp b)
forall a. C a => T a (Exp a)
Arg.primitive T b (Exp b)
-> (forall al.
    C al =>
    T IO ((z, al), al) (Array sh c) (IO (Array sh c)))
-> T IO (z, al) (Exp b -> Array sh c) (b -> IO (Array sh c))
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)
*-> T IO ((z, al), al) (Array sh c) (IO (Array sh c))
forall al.
C al =>
T IO ((z, al), al) (Array sh c) (IO (Array sh c))
forall sh ix p a.
(C sh, Index sh ~ ix, C sh, C p, C a) =>
T IO p (Array sh a) (IO (Array sh a))
array


_example2 ::
   (Marshal.C sh, Shape.C sh,
    Marshal.C a, Marshal.C b, Storable.C c) =>
   (Exp a -> Exp b -> Core.Array sh c) ->
   IO (a -> b -> IO (Phys.Array sh c))
_example2 :: forall sh a b c.
(C sh, C sh, C a, C b, C c) =>
(Exp a -> Exp b -> Array sh c) -> IO (a -> b -> IO (Array sh c))
_example2 = T IO () (Exp a -> Exp b -> Array sh c) (a -> b -> IO (Array sh c))
-> (Exp a -> Exp b -> Array sh c) -> IO (a -> b -> IO (Array sh c))
forall (m :: * -> *) fdsl f.
Functor m =>
T m () fdsl f -> fdsl -> m f
run (T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al.
    C al =>
    T IO ((), al) (Exp b -> Array sh c) (b -> IO (Array sh c)))
-> T IO
     ()
     (Exp a -> Exp b -> Array sh c)
     (a -> b -> IO (Array sh c))
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)
*-> T b (Exp b)
forall a. C a => T a (Exp a)
Arg.primitive T b (Exp b)
-> (forall al.
    C al =>
    T IO (((), al), al) (Array sh c) (IO (Array sh c)))
-> T IO ((), al) (Exp b -> Array sh c) (b -> IO (Array sh c))
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)
*-> T IO (((), al), al) (Array sh c) (IO (Array sh c))
forall al.
C al =>
T IO (((), al), al) (Array sh c) (IO (Array sh c))
forall sh ix p a.
(C sh, Index sh ~ ix, C sh, C p, C a) =>
T IO p (Array sh a) (IO (Array sh a))
array)

_example2exp ::
   (Marshal.C a, Marshal.C b, Storable.C c) =>
   (Exp a -> Exp b -> Exp c) ->
   IO (a -> b -> IO c)
_example2exp :: forall a b c.
(C a, C b, C c) =>
(Exp a -> Exp b -> Exp c) -> IO (a -> b -> IO c)
_example2exp = T IO () (Exp a -> Exp b -> Exp c) (a -> b -> IO c)
-> (Exp a -> Exp b -> Exp c) -> IO (a -> b -> IO c)
forall (m :: * -> *) fdsl f.
Functor m =>
T m () fdsl f -> fdsl -> m f
run (T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al. C al => T IO ((), al) (Exp b -> Exp c) (b -> IO c))
-> T IO () (Exp a -> Exp b -> Exp c) (a -> b -> IO c)
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)
*-> T b (Exp b)
forall a. C a => T a (Exp a)
Arg.primitive T b (Exp b)
-> (forall al. C al => T IO (((), al), al) (Exp c) (IO c))
-> T IO ((), al) (Exp b -> Exp c) (b -> IO c)
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)
*-> T IO (((), al), al) (Exp c) (IO c)
forall al. C al => T IO (((), al), al) (Exp c) (IO c)
forall p a. (C p, C a) => T IO p (Exp a) (IO a)
storable)

_example2marshal ::
   (Marshal.C a, Marshal.C b, Marshal.C c) =>
   (Exp a -> Exp b -> Exp c) ->
   IO (a -> b -> IO c)
_example2marshal :: forall a b c.
(C a, C b, C c) =>
(Exp a -> Exp b -> Exp c) -> IO (a -> b -> IO c)
_example2marshal = T IO () (Exp a -> Exp b -> Exp c) (a -> b -> IO c)
-> (Exp a -> Exp b -> Exp c) -> IO (a -> b -> IO c)
forall (m :: * -> *) fdsl f.
Functor m =>
T m () fdsl f -> fdsl -> m f
run (T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al. C al => T IO ((), al) (Exp b -> Exp c) (b -> IO c))
-> T IO () (Exp a -> Exp b -> Exp c) (a -> b -> IO c)
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)
*-> T b (Exp b)
forall a. C a => T a (Exp a)
Arg.primitive T b (Exp b)
-> (forall al. C al => T IO (((), al), al) (Exp c) (IO c))
-> T IO ((), al) (Exp b -> Exp c) (b -> IO c)
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)
*-> T IO (((), al), al) (Exp c) (IO c)
forall al. C al => T IO (((), al), al) (Exp c) (IO c)
forall p a. (C p, C a) => T IO p (Exp a) (IO a)
marshal)

_example2scatter ::
   (Shape.C sh0, Shape.C sh1, Marshal.C sh1,
    Marshal.C a, Marshal.C b, Storable.C c) =>
   (Exp a -> Exp b -> PhysP.Scatter sh0 sh1 c) ->
   IO (a -> b -> IO (Array.Array sh1 c))
_example2scatter :: forall sh0 sh1 a b c.
(C sh0, C sh1, C sh1, C a, C b, C c) =>
(Exp a -> Exp b -> Scatter sh0 sh1 c)
-> IO (a -> b -> IO (Array sh1 c))
_example2scatter = T IO
  ()
  (Exp a -> Exp b -> Scatter sh0 sh1 c)
  (a -> b -> IO (Array sh1 c))
-> (Exp a -> Exp b -> Scatter sh0 sh1 c)
-> IO (a -> b -> IO (Array sh1 c))
forall (m :: * -> *) fdsl f.
Functor m =>
T m () fdsl f -> fdsl -> m f
run (T a (Exp a)
forall a. C a => T a (Exp a)
Arg.primitive T a (Exp a)
-> (forall al.
    C al =>
    T IO ((), al) (Exp b -> Scatter sh0 sh1 c) (b -> IO (Array sh1 c)))
-> T IO
     ()
     (Exp a -> Exp b -> Scatter sh0 sh1 c)
     (a -> b -> IO (Array sh1 c))
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)
*-> T b (Exp b)
forall a. C a => T a (Exp a)
Arg.primitive T b (Exp b)
-> (forall al.
    C al =>
    T IO (((), al), al) (Scatter sh0 sh1 c) (IO (Array sh1 c)))
-> T IO
     ((), al)
     (Exp b -> Scatter sh0 sh1 c)
     (b -> IO (Array sh1 c))
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)
*-> T IO (((), al), al) (Scatter sh0 sh1 c) (IO (Array sh1 c))
forall al.
C al =>
T IO (((), al), al) (Scatter sh0 sh1 c) (IO (Array sh1 c))
forall sh0 sh1 p a.
(C sh0, C sh1, C sh1, C p, C a) =>
T IO p (Scatter sh0 sh1 a) (IO (Array sh1 a))
scatter)




singleton :: Exp a -> Core.Array () a
singleton :: forall a. Exp a -> Array () a
singleton = Exp a -> Array () a
forall sh a. Scalar sh => Exp a -> Array sh a
Core.fromScalar

storable :: (Marshal.C p, Storable.C a) => Run.T IO p (Exp a) (IO a)
storable :: forall p a. (C p, C a) => T IO p (Exp a) (IO a)
storable = ((Exp p -> Exp a) -> IO (Creator p -> IO a))
-> T IO p (Exp a) (IO a)
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (((Exp p -> Exp a) -> IO (Creator p -> IO a))
 -> T IO p (Exp a) (IO a))
-> ((Exp p -> Exp a) -> IO (Creator p -> IO a))
-> T IO p (Exp a) (IO a)
forall a b. (a -> b) -> a -> b
$ Parametric p (Array () a) -> IO (Creator p -> IO a)
forall p z a.
(C p, Scalar z, C a) =>
Parametric p (Array z a) -> IO (Rendered p a)
PhysP.the (Parametric p (Array () a) -> IO (Creator p -> IO a))
-> ((Exp p -> Exp a) -> Parametric p (Array () a))
-> (Exp p -> Exp a)
-> IO (Creator p -> IO a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp a -> Array () a)
-> (Exp p -> Exp a) -> Parametric p (Array () a)
forall a b. (a -> b) -> (Exp p -> a) -> Exp p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Exp a -> Array () a
forall a. Exp a -> Array () a
singleton

marshal :: (Marshal.C p, Marshal.C a) => Run.T IO p (Exp a) (IO a)
marshal :: forall p a. (C p, C a) => T IO p (Exp a) (IO a)
marshal = ((Exp p -> Exp a) -> IO (Creator p -> IO a))
-> T IO p (Exp a) (IO a)
forall (m :: * -> *) p fdsl f.
((Exp p -> fdsl) -> m (Creator p -> f)) -> T m p fdsl f
Run.Cons (((Exp p -> Exp a) -> IO (Creator p -> IO a))
 -> T IO p (Exp a) (IO a))
-> ((Exp p -> Exp a) -> IO (Creator p -> IO a))
-> T IO p (Exp a) (IO a)
forall a b. (a -> b) -> a -> b
$ Parametric p (Array () a) -> IO (Creator p -> IO a)
forall p z a.
(C p, Scalar z, C a) =>
Parametric p (Array z a) -> IO (Rendered p a)
PhysP.theMarshal (Parametric p (Array () a) -> IO (Creator p -> IO a))
-> ((Exp p -> Exp a) -> Parametric p (Array () a))
-> (Exp p -> Exp a)
-> IO (Creator p -> IO a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp a -> Array () a)
-> (Exp p -> Exp a) -> Parametric p (Array () a)
forall a b. (a -> b) -> (Exp p -> a) -> Exp p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Exp a -> Array () a
forall a. Exp a -> Array () a
singleton

array ::
   (Shape.C sh, Shape.Index sh ~ ix, Marshal.C sh,
    Marshal.C p, Storable.C a) =>
   Run.T IO p (Core.Array sh a) (IO (Phys.Array sh a))
array :: forall sh ix p a.
(C sh, Index sh ~ ix, C sh, C p, C a) =>
T IO p (Array sh a) (IO (Array sh a))
array = ((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


scatter ::
   (Shape.C sh0, Shape.C sh1, Marshal.C sh1, Marshal.C p, Storable.C a) =>
   Run.T IO p (PhysP.Scatter sh0 sh1 a) (IO (Array.Array sh1 a))
scatter :: forall sh0 sh1 p a.
(C sh0, C sh1, C sh1, C p, C a) =>
T IO p (Scatter sh0 sh1 a) (IO (Array sh1 a))
scatter = ((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