{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Data.Array.Knead.Parameterized.PhysicalHull (
   render,
   MapFilter(..),
   mapFilter,
   FilterOuter(..),
   filterOuter,
   Scatter(..),
   scatter,
   ScatterMaybe(..),
   scatterMaybe,
   MapAccumLSimple(..),
   mapAccumLSimple,
   MapAccumLSequence(..),
   mapAccumLSequence,
   MapAccumL(..),
   mapAccumL,
   FoldOuterL(..),
   foldOuterL,
   AddDimension(..),
   addDimension,
   ) where

import qualified Data.Array.Knead.Parameterized.Private as Sym
import qualified Data.Array.Knead.Symbolic.PhysicalPrivate as Priv
import qualified Data.Array.Knead.Symbolic.Private as Core
import qualified Data.Array.Knead.Shape as Shape
import qualified Data.Array.Knead.Expression as Expr
import Data.Array.Knead.Symbolic.PhysicalPrivate (MarshalPtr)

import Data.Array.Comfort.Storable.Unchecked (Array(Array))

import qualified LLVM.DSL.Execution as Code
import LLVM.DSL.Expression (Exp, unExp)

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.Memory as Memory
import qualified LLVM.Extra.Arithmetic as A

import qualified LLVM.Core as LLVM

import Foreign.Marshal.Array (allocaArray, )
import Foreign.Marshal.Alloc (alloca, )
import Foreign.Storable (Storable, peek, peekElemOff, )
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrArray, )
import Foreign.Ptr (FunPtr, Ptr, )

import Control.Exception (bracket, )
import Control.Monad.HT (void, )
import Control.Applicative (liftA2, )


mallocArray :: (Storable a) => Shape.Size -> IO (ForeignPtr a)
mallocArray :: forall a. Storable a => Size -> IO (ForeignPtr a)
mallocArray = Int -> IO (ForeignPtr a)
forall a. Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrArray (Int -> IO (ForeignPtr a))
-> (Size -> Int) -> Size -> IO (ForeignPtr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Size -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral


type Importer f = FunPtr f -> f


foreign import ccall safe "dynamic" callShaper ::
   Importer (LLVM.Ptr param -> LLVM.Ptr shape -> IO Shape.Size)

foreign import ccall safe "dynamic" callFill ::
   Importer (LLVM.Ptr param -> LLVM.Ptr shape -> Ptr a -> IO ())


{-
Attention:
The 'fill' function may alter the shape.
An example is 'mapFilter'.
-}
materialize ::
   (Shape.C sh, Marshal.C sh, Storable.C a) =>
   String ->
   (core -> Exp sh) ->
   (core ->
    LLVM.Value (MarshalPtr sh) -> LLVM.Value (Ptr a) ->
    LLVM.CodeGenFunction () ()) ->
   Sym.Hull p core -> IO (p -> IO (Array sh a))
materialize :: forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
name core -> Exp sh
shape core
-> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ()
fill (Sym.Hull T parameter -> core
core p -> IO (context, parameter)
create context -> IO ()
delete) = do
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size
fsh, Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ()
farr) <-
      String
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> IO
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall funcs. String -> Exec funcs -> IO funcs
Code.compile String
name (Exec
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
    Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
 -> IO
      (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
       Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ()))
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> IO
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall a b. (a -> b) -> a -> b
$
      ((Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
 -> (Ptr (Struct (Repr parameter))
     -> MarshalPtr sh -> Ptr a -> IO ())
 -> (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
     Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ()))
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall a b c.
(a -> b -> c)
-> Compose CodeGenModule EngineAccess a
-> Compose CodeGenModule EngineAccess b
-> Compose CodeGenModule EngineAccess c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,)
         (Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall param shape. Importer (Ptr param -> Ptr shape -> IO Size)
callShaper String
"shape" (CodeGen
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size))
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (MarshalPtr sh)
resultPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction Size (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            T sh
sh <- Exp sh -> forall r. CodeGenFunction r (T sh)
forall a. Exp a -> forall r. CodeGenFunction r (T a)
unExp (Exp sh -> forall r. CodeGenFunction r (T sh))
-> Exp sh -> forall r. CodeGenFunction r (T sh)
forall a b. (a -> b) -> a -> b
$ core -> Exp sh
shape (core -> Exp sh) -> core -> Exp sh
forall a b. (a -> b) -> a -> b
$ T parameter -> core
core T parameter
param
            T sh -> Value (Ptr (Struct (T sh))) -> CodeGenFunction Size ()
forall r.
T sh -> Value (Ptr (Struct (T sh))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store T sh
sh Value (MarshalPtr sh)
Value (Ptr (Struct (T sh)))
resultPtr
            T sh -> CodeGenFunction Size (Value Size)
forall r. T sh -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
Shape.size T sh
sh)
         (Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall param shape a.
Importer (Ptr param -> Ptr shape -> Ptr a -> IO ())
callFill String
"fill" (CodeGen
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ()))
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ())
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (MarshalPtr sh)
shapePtr Value (Ptr a)
bufferPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction () (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            core
-> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ()
fill (T parameter -> core
core T parameter
param) Value (MarshalPtr sh)
shapePtr Value (Ptr a)
bufferPtr)

   (p -> IO (Array sh a)) -> IO (p -> IO (Array sh a))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((p -> IO (Array sh a)) -> IO (p -> IO (Array sh a)))
-> (p -> IO (Array sh a)) -> IO (p -> IO (Array sh a))
forall a b. (a -> b) -> a -> b
$ \p
p ->
      IO (context, parameter)
-> ((context, parameter) -> IO ())
-> ((context, parameter) -> IO (Array sh a))
-> IO (Array sh a)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (p -> IO (context, parameter)
create p
p) (context -> IO ()
delete (context -> IO ())
-> ((context, parameter) -> context)
-> (context, parameter)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (context, parameter) -> context
forall a b. (a, b) -> a
fst) (((context, parameter) -> IO (Array sh a)) -> IO (Array sh a))
-> ((context, parameter) -> IO (Array sh a)) -> IO (Array sh a)
forall a b. (a -> b) -> a -> b
$ \(context
_ctx, parameter
param) ->
      (MarshalPtr sh -> IO (Array sh a)) -> IO (Array sh a)
forall a b. IsType a => (Ptr a -> IO b) -> IO b
Marshal.alloca ((MarshalPtr sh -> IO (Array sh a)) -> IO (Array sh a))
-> (MarshalPtr sh -> IO (Array sh a)) -> IO (Array sh a)
forall a b. (a -> b) -> a -> b
$ \MarshalPtr sh
shptr ->
      parameter
-> (Ptr (Struct (Repr parameter)) -> IO (Array sh a))
-> IO (Array sh a)
forall a b. C a => a -> (Ptr (Struct a) -> IO b) -> IO b
Marshal.with parameter
param ((Ptr (Struct (Repr parameter)) -> IO (Array sh a))
 -> IO (Array sh a))
-> (Ptr (Struct (Repr parameter)) -> IO (Array sh a))
-> IO (Array sh a)
forall a b. (a -> b) -> a -> b
$ \Ptr (Struct (Repr parameter))
paramPtr -> do
         ForeignPtr a
fptr <- Size -> IO (ForeignPtr a)
forall a. Storable a => Size -> IO (ForeignPtr a)
mallocArray (Size -> IO (ForeignPtr a)) -> IO Size -> IO (ForeignPtr a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size
fsh Ptr (Struct (Repr parameter))
paramPtr MarshalPtr sh
shptr
         ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
fptr ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> Ptr a -> IO ()
farr Ptr (Struct (Repr parameter))
paramPtr MarshalPtr sh
shptr
         sh
sh <- MarshalPtr sh -> IO sh
forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> IO a
Marshal.peek MarshalPtr sh
shptr
         Array sh a -> IO (Array sh a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (sh -> ForeignPtr a -> Array sh a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array sh
sh ForeignPtr a
fptr)


foreign import ccall safe "dynamic" callFillExpArray ::
   Importer (LLVM.Ptr param -> Ptr final -> LLVM.Ptr shape -> Ptr a -> IO ())


materializeExpArray ::
   (Shape.C sh, Marshal.C sh, Storable.C a, Storable.C b) =>
   String ->
   (core -> Exp sh) ->
   (core ->
    LLVM.Value (Ptr b) ->
    LLVM.Value (MarshalPtr sh) ->
    LLVM.Value (Ptr a) ->
    LLVM.CodeGenFunction () ()) ->
   Sym.Hull p core -> IO (p -> IO (b, Array sh a))
materializeExpArray :: forall sh a b core p.
(C sh, C sh, C a, C b) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (Ptr b)
    -> Value (MarshalPtr sh)
    -> Value (Ptr a)
    -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (b, Array sh a))
materializeExpArray String
name core -> Exp sh
shape core
-> Value (Ptr b)
-> Value (MarshalPtr sh)
-> Value (Ptr a)
-> CodeGenFunction () ()
fill (Sym.Hull T parameter -> core
core p -> IO (context, parameter)
create context -> IO ()
delete) = do
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size
fsh, Ptr (Struct (Repr parameter))
-> Ptr b -> MarshalPtr sh -> Ptr a -> IO ()
farr) <-
      String
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> IO
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall funcs. String -> Exec funcs -> IO funcs
Code.compile String
name (Exec
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
    Ptr (Struct (Repr parameter))
    -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
 -> IO
      (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
       Ptr (Struct (Repr parameter))
       -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ()))
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> IO
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall a b. (a -> b) -> a -> b
$
      ((Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
 -> (Ptr (Struct (Repr parameter))
     -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
 -> (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
     Ptr (Struct (Repr parameter))
     -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ()))
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> Exec
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size,
      Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall a b c.
(a -> b -> c)
-> Compose CodeGenModule EngineAccess a
-> Compose CodeGenModule EngineAccess b
-> Compose CodeGenModule EngineAccess c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,)
         (Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall param shape. Importer (Ptr param -> Ptr shape -> IO Size)
callShaper String
"shape" (CodeGen
   (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size))
-> CodeGen
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size)
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (MarshalPtr sh)
resultPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction Size (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            T sh
sh <- Exp sh -> forall r. CodeGenFunction r (T sh)
forall a. Exp a -> forall r. CodeGenFunction r (T a)
unExp (Exp sh -> forall r. CodeGenFunction r (T sh))
-> Exp sh -> forall r. CodeGenFunction r (T sh)
forall a b. (a -> b) -> a -> b
$ core -> Exp sh
shape (core -> Exp sh) -> core -> Exp sh
forall a b. (a -> b) -> a -> b
$ T parameter -> core
core T parameter
param
            T sh -> Value (Ptr (Struct (T sh))) -> CodeGenFunction Size ()
forall r.
T sh -> Value (Ptr (Struct (T sh))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store T sh
sh Value (MarshalPtr sh)
Value (Ptr (Struct (T sh)))
resultPtr
            T sh -> CodeGenFunction Size (Value Size)
forall r. T sh -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
Shape.size T sh
sh)
         (Importer
  (Ptr (Struct (Repr parameter))
   -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter))
   -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall param final shape a.
Importer (Ptr param -> Ptr final -> Ptr shape -> Ptr a -> IO ())
callFillExpArray String
"fill" (CodeGen
   (Ptr (Struct (Repr parameter))
    -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter))
       -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ()))
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> Ptr b -> MarshalPtr sh -> Ptr a -> IO ())
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (Ptr b)
finalPtr Value (MarshalPtr sh)
shapePtr Value (Ptr a)
bufferPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction () (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            core
-> Value (Ptr b)
-> Value (MarshalPtr sh)
-> Value (Ptr a)
-> CodeGenFunction () ()
fill (T parameter -> core
core T parameter
param) Value (Ptr b)
finalPtr Value (MarshalPtr sh)
shapePtr Value (Ptr a)
bufferPtr)

   (p -> IO (b, Array sh a)) -> IO (p -> IO (b, Array sh a))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((p -> IO (b, Array sh a)) -> IO (p -> IO (b, Array sh a)))
-> (p -> IO (b, Array sh a)) -> IO (p -> IO (b, Array sh a))
forall a b. (a -> b) -> a -> b
$ \p
p ->
      IO (context, parameter)
-> ((context, parameter) -> IO ())
-> ((context, parameter) -> IO (b, Array sh a))
-> IO (b, Array sh a)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (p -> IO (context, parameter)
create p
p) (context -> IO ()
delete (context -> IO ())
-> ((context, parameter) -> context)
-> (context, parameter)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (context, parameter) -> context
forall a b. (a, b) -> a
fst) (((context, parameter) -> IO (b, Array sh a))
 -> IO (b, Array sh a))
-> ((context, parameter) -> IO (b, Array sh a))
-> IO (b, Array sh a)
forall a b. (a -> b) -> a -> b
$ \(context
_ctx, parameter
param) ->
      (MarshalPtr sh -> IO (b, Array sh a)) -> IO (b, Array sh a)
forall a b. IsType a => (Ptr a -> IO b) -> IO b
Marshal.alloca ((MarshalPtr sh -> IO (b, Array sh a)) -> IO (b, Array sh a))
-> (MarshalPtr sh -> IO (b, Array sh a)) -> IO (b, Array sh a)
forall a b. (a -> b) -> a -> b
$ \MarshalPtr sh
shptr ->
      (Ptr b -> IO (b, Array sh a)) -> IO (b, Array sh a)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr b -> IO (b, Array sh a)) -> IO (b, Array sh a))
-> (Ptr b -> IO (b, Array sh a)) -> IO (b, Array sh a)
forall a b. (a -> b) -> a -> b
$ \Ptr b
finalPtr ->
      parameter
-> (Ptr (Struct (Repr parameter)) -> IO (b, Array sh a))
-> IO (b, Array sh a)
forall a b. C a => a -> (Ptr (Struct a) -> IO b) -> IO b
Marshal.with parameter
param ((Ptr (Struct (Repr parameter)) -> IO (b, Array sh a))
 -> IO (b, Array sh a))
-> (Ptr (Struct (Repr parameter)) -> IO (b, Array sh a))
-> IO (b, Array sh a)
forall a b. (a -> b) -> a -> b
$ \Ptr (Struct (Repr parameter))
paramPtr -> do
         ForeignPtr a
fptr <- Size -> IO (ForeignPtr a)
forall a. Storable a => Size -> IO (ForeignPtr a)
mallocArray (Size -> IO (ForeignPtr a)) -> IO Size -> IO (ForeignPtr a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (Struct (Repr parameter)) -> MarshalPtr sh -> IO Size
fsh Ptr (Struct (Repr parameter))
paramPtr MarshalPtr sh
shptr
         ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
fptr ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr (Struct (Repr parameter))
-> Ptr b -> MarshalPtr sh -> Ptr a -> IO ()
farr Ptr (Struct (Repr parameter))
paramPtr Ptr b
finalPtr MarshalPtr sh
shptr
         sh
sh <- MarshalPtr sh -> IO sh
forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> IO a
Marshal.peek MarshalPtr sh
shptr
         b
final <- Ptr b -> IO b
forall a. Storable a => Ptr a -> IO a
peek Ptr b
finalPtr
         (b, Array sh a) -> IO (b, Array sh a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (b
final, sh -> ForeignPtr a -> Array sh a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array sh
sh ForeignPtr a
fptr)


foreign import ccall safe "dynamic" callShaper2 ::
   Importer
      (LLVM.Ptr param ->
       LLVM.Ptr shapeA -> LLVM.Ptr shapeB -> Ptr Shape.Size -> IO ())

foreign import ccall safe "dynamic" callFill2 ::
   Importer
      (LLVM.Ptr param ->
       LLVM.Ptr shapeA -> Ptr a -> LLVM.Ptr shapeB -> Ptr b -> IO ())


materialize2 ::
   (Shape.C sha, Marshal.C sha,
    Shape.C shb, Marshal.C shb,
    Storable.C a, Storable.C b) =>
   String ->
   (core -> Exp (sha,shb)) ->
   (core ->
    (LLVM.Value (MarshalPtr sha), LLVM.Value (Ptr a)) ->
    (LLVM.Value (MarshalPtr shb), LLVM.Value (Ptr b)) ->
    LLVM.CodeGenFunction () ()) ->
   Sym.Hull p core -> IO (p -> IO (Array sha a, Array shb b))
materialize2 :: forall sha shb a b core p.
(C sha, C sha, C shb, C shb, C a, C b) =>
String
-> (core -> Exp (sha, shb))
-> (core
    -> (Value (MarshalPtr sha), Value (Ptr a))
    -> (Value (MarshalPtr shb), Value (Ptr b))
    -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sha a, Array shb b))
materialize2 String
name core -> Exp (sha, shb)
shape core
-> (Value (MarshalPtr sha), Value (Ptr a))
-> (Value (MarshalPtr shb), Value (Ptr b))
-> CodeGenFunction () ()
fill (Sym.Hull T parameter -> core
core p -> IO (context, parameter)
create context -> IO ()
delete) = do
   (Ptr (Struct (Repr parameter))
-> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ()
fsh, Ptr (Struct (Repr parameter))
-> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ()
farr) <-
      String
-> Exec
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
      Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> IO
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
      Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall funcs. String -> Exec funcs -> IO funcs
Code.compile String
name (Exec
   (Ptr (Struct (Repr parameter))
    -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
    Ptr (Struct (Repr parameter))
    -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
 -> IO
      (Ptr (Struct (Repr parameter))
       -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
       Ptr (Struct (Repr parameter))
       -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ()))
-> Exec
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
      Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> IO
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
      Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall a b. (a -> b) -> a -> b
$
      ((Ptr (Struct (Repr parameter))
  -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
 -> (Ptr (Struct (Repr parameter))
     -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
 -> (Ptr (Struct (Repr parameter))
     -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
     Ptr (Struct (Repr parameter))
     -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ()))
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> Exec
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO (),
      Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall a b c.
(a -> b -> c)
-> Compose CodeGenModule EngineAccess a
-> Compose CodeGenModule EngineAccess b
-> Compose CodeGenModule EngineAccess c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,)
         (Importer
  (Ptr (Struct (Repr parameter))
   -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter))
   -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
forall param shapeA shapeB.
Importer
  (Ptr param -> Ptr shapeA -> Ptr shapeB -> Ptr Size -> IO ())
callShaper2 String
"shape" (CodeGen
   (Ptr (Struct (Repr parameter))
    -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter))
       -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ()))
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ())
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (MarshalPtr sha)
shapeAPtr Value (MarshalPtr shb)
shapeBPtr Value (Ptr Size)
sizesPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction () (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            (T sha
sha,T shb
shb) <- (T (sha, shb) -> (T sha, T shb))
-> CodeGenFunction () (T (sha, shb))
-> CodeGenFunction () (T sha, T shb)
forall a b.
(a -> b) -> CodeGenFunction () a -> CodeGenFunction () b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap T (sha, shb) -> (T sha, T shb)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip (CodeGenFunction () (T (sha, shb))
 -> CodeGenFunction () (T sha, T shb))
-> CodeGenFunction () (T (sha, shb))
-> CodeGenFunction () (T sha, T shb)
forall a b. (a -> b) -> a -> b
$ Exp (sha, shb) -> forall r. CodeGenFunction r (T (sha, shb))
forall a. Exp a -> forall r. CodeGenFunction r (T a)
unExp (Exp (sha, shb) -> forall r. CodeGenFunction r (T (sha, shb)))
-> Exp (sha, shb) -> forall r. CodeGenFunction r (T (sha, shb))
forall a b. (a -> b) -> a -> b
$ core -> Exp (sha, shb)
shape (core -> Exp (sha, shb)) -> core -> Exp (sha, shb)
forall a b. (a -> b) -> a -> b
$ T parameter -> core
core T parameter
param
            T sha -> Value (Ptr (Struct (T sha))) -> CodeGenFunction () ()
forall r.
T sha -> Value (Ptr (Struct (T sha))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store T sha
sha Value (MarshalPtr sha)
Value (Ptr (Struct (T sha)))
shapeAPtr
            T shb -> Value (Ptr (Struct (T shb))) -> CodeGenFunction () ()
forall r.
T shb -> Value (Ptr (Struct (T shb))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store T shb
shb Value (MarshalPtr shb)
Value (Ptr (Struct (T shb)))
shapeBPtr
            Value (Ptr Size)
sizeAPtr <- Value (Ptr Size) -> CodeGenFunction () (Value (Ptr Size))
forall (value :: * -> *) a b r.
(ValueCons value, IsSized a, IsSized b, SizeOf a ~ SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.bitcast Value (Ptr Size)
sizesPtr
            (Value Size -> Value (Ptr Size) -> CodeGenFunction () ())
-> Value (Ptr Size) -> Value Size -> CodeGenFunction () ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Value Size -> Value (Ptr Size) -> CodeGenFunction () ()
forall a r. Value a -> Value (Ptr a) -> CodeGenFunction r ()
LLVM.store Value (Ptr Size)
sizeAPtr (Value Size -> CodeGenFunction () ())
-> CodeGenFunction () (Value Size) -> CodeGenFunction () ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T sha -> CodeGenFunction () (Value Size)
forall r. T sha -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
Shape.size T sha
sha
            Value (Ptr Size)
sizeBPtr <- Value (Ptr Size) -> CodeGenFunction () (Value (Ptr Size))
forall a r. Value (Ptr a) -> CodeGenFunction r (Value (Ptr a))
A.advanceArrayElementPtr Value (Ptr Size)
sizeAPtr
            (Value Size -> Value (Ptr Size) -> CodeGenFunction () ())
-> Value (Ptr Size) -> Value Size -> CodeGenFunction () ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Value Size -> Value (Ptr Size) -> CodeGenFunction () ()
forall a r. Value a -> Value (Ptr a) -> CodeGenFunction r ()
LLVM.store Value (Ptr Size)
sizeBPtr (Value Size -> CodeGenFunction () ())
-> CodeGenFunction () (Value Size) -> CodeGenFunction () ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T shb -> CodeGenFunction () (Value Size)
forall r. T shb -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
Shape.size T shb
shb)
         (Importer
  (Ptr (Struct (Repr parameter))
   -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> String
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall f.
(ExecutionFunction f, C f) =>
Importer f -> String -> CodeGen f -> Exec f
Code.createFunction Importer
  (Ptr (Struct (Repr parameter))
   -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall param shapeA a shapeB b.
Importer
  (Ptr param -> Ptr shapeA -> Ptr a -> Ptr shapeB -> Ptr b -> IO ())
callFill2 String
"fill" (CodeGen
   (Ptr (Struct (Repr parameter))
    -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
 -> Compose
      CodeGenModule
      EngineAccess
      (Ptr (Struct (Repr parameter))
       -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ()))
-> CodeGen
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
-> Compose
     CodeGenModule
     EngineAccess
     (Ptr (Struct (Repr parameter))
      -> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ())
forall a b. (a -> b) -> a -> b
$
          \Value (Ptr (Struct (Repr parameter)))
paramPtr Value (MarshalPtr sha)
shapeAPtr Value (Ptr a)
bufferAPtr Value (MarshalPtr shb)
shapeBPtr Value (Ptr b)
bufferBPtr -> do
            T parameter
param <- Value (Ptr (Struct (T parameter)))
-> CodeGenFunction () (T parameter)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r.
Value (Ptr (Struct (T parameter)))
-> CodeGenFunction r (T parameter)
Memory.load Value (Ptr (Struct (Repr parameter)))
Value (Ptr (Struct (T parameter)))
paramPtr
            core
-> (Value (MarshalPtr sha), Value (Ptr a))
-> (Value (MarshalPtr shb), Value (Ptr b))
-> CodeGenFunction () ()
fill (T parameter -> core
core T parameter
param) (Value (MarshalPtr sha)
shapeAPtr, Value (Ptr a)
bufferAPtr) (Value (MarshalPtr shb)
shapeBPtr, Value (Ptr b)
bufferBPtr))

   (p -> IO (Array sha a, Array shb b))
-> IO (p -> IO (Array sha a, Array shb b))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((p -> IO (Array sha a, Array shb b))
 -> IO (p -> IO (Array sha a, Array shb b)))
-> (p -> IO (Array sha a, Array shb b))
-> IO (p -> IO (Array sha a, Array shb b))
forall a b. (a -> b) -> a -> b
$ \p
p ->
      IO (context, parameter)
-> ((context, parameter) -> IO ())
-> ((context, parameter) -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (p -> IO (context, parameter)
create p
p) (context -> IO ()
delete (context -> IO ())
-> ((context, parameter) -> context)
-> (context, parameter)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (context, parameter) -> context
forall a b. (a, b) -> a
fst) (((context, parameter) -> IO (Array sha a, Array shb b))
 -> IO (Array sha a, Array shb b))
-> ((context, parameter) -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. (a -> b) -> a -> b
$ \(context
_ctx, parameter
param) ->
      (MarshalPtr sha -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. IsType a => (Ptr a -> IO b) -> IO b
Marshal.alloca ((MarshalPtr sha -> IO (Array sha a, Array shb b))
 -> IO (Array sha a, Array shb b))
-> (MarshalPtr sha -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. (a -> b) -> a -> b
$ \MarshalPtr sha
shaPtr ->
      (MarshalPtr shb -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. IsType a => (Ptr a -> IO b) -> IO b
Marshal.alloca ((MarshalPtr shb -> IO (Array sha a, Array shb b))
 -> IO (Array sha a, Array shb b))
-> (MarshalPtr shb -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. (a -> b) -> a -> b
$ \MarshalPtr shb
shbPtr ->
      Int
-> (Ptr Size -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
2 ((Ptr Size -> IO (Array sha a, Array shb b))
 -> IO (Array sha a, Array shb b))
-> (Ptr Size -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. (a -> b) -> a -> b
$ \Ptr Size
sizesPtr ->
      parameter
-> (Ptr (Struct (Repr parameter)) -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. C a => a -> (Ptr (Struct a) -> IO b) -> IO b
Marshal.with parameter
param ((Ptr (Struct (Repr parameter)) -> IO (Array sha a, Array shb b))
 -> IO (Array sha a, Array shb b))
-> (Ptr (Struct (Repr parameter)) -> IO (Array sha a, Array shb b))
-> IO (Array sha a, Array shb b)
forall a b. (a -> b) -> a -> b
$ \Ptr (Struct (Repr parameter))
paramPtr -> do
         Ptr (Struct (Repr parameter))
-> MarshalPtr sha -> MarshalPtr shb -> Ptr Size -> IO ()
fsh Ptr (Struct (Repr parameter))
paramPtr MarshalPtr sha
shaPtr MarshalPtr shb
shbPtr Ptr Size
sizesPtr
         ForeignPtr a
afptr <- Size -> IO (ForeignPtr a)
forall a. Storable a => Size -> IO (ForeignPtr a)
mallocArray (Size -> IO (ForeignPtr a)) -> IO Size -> IO (ForeignPtr a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Size -> Int -> IO Size
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Size
sizesPtr Int
0
         ForeignPtr b
bfptr <- Size -> IO (ForeignPtr b)
forall a. Storable a => Size -> IO (ForeignPtr a)
mallocArray (Size -> IO (ForeignPtr b)) -> IO Size -> IO (ForeignPtr b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Size -> Int -> IO Size
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Size
sizesPtr Int
1
         ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
afptr ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
aptr ->
            ForeignPtr b -> (Ptr b -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr b
bfptr ((Ptr b -> IO ()) -> IO ()) -> (Ptr b -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr b
bptr ->
            Ptr (Struct (Repr parameter))
-> MarshalPtr sha -> Ptr a -> MarshalPtr shb -> Ptr b -> IO ()
farr Ptr (Struct (Repr parameter))
paramPtr MarshalPtr sha
shaPtr Ptr a
aptr MarshalPtr shb
shbPtr Ptr b
bptr
         sha
sha <- MarshalPtr sha -> IO sha
forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> IO a
Marshal.peek MarshalPtr sha
shaPtr
         shb
shb <- MarshalPtr shb -> IO shb
forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> IO a
Marshal.peek MarshalPtr shb
shbPtr
         (Array sha a, Array shb b) -> IO (Array sha a, Array shb b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (sha -> ForeignPtr a -> Array sha a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array sha
sha ForeignPtr a
afptr, shb -> ForeignPtr b -> Array shb b
forall sh a. sh -> ForeignPtr a -> Array sh a
Array shb
shb ForeignPtr b
bfptr)


render ::
   (Shape.C sh, Shape.Index sh ~ ix, Marshal.C sh,
    Storable.C a) =>
   Sym.Hull p (Core.Array sh a) -> IO (p -> IO (Array sh a))
render :: forall sh ix a p.
(C sh, Index sh ~ ix, C sh, C a) =>
Hull p (Array sh a) -> IO (p -> IO (Array sh a))
render =
   String
-> (Array sh a -> Exp sh)
-> (Array sh a
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p (Array sh a)
-> IO (p -> IO (Array sh a))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"render" Array sh a -> Exp sh
forall sh a. Array sh a -> Exp sh
Core.shape
      (\(Core.Array Exp sh
esh forall r. Val (Index sh) -> Code r a
code) Value (MarshalPtr sh)
shapePtr Value (Ptr a)
bufferPtr -> do
         let step :: T ix -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a))
step T ix
ix Value (Ptr a)
p = (T a -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a)))
-> Value (Ptr a) -> T a -> CodeGenFunction () (Value (Ptr a))
forall a b c. (a -> b -> c) -> b -> a -> c
flip T a -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a))
forall a ptr r.
(C a, Value (Ptr a) ~ ptr) =>
T a -> ptr -> CodeGenFunction r ptr
Storable.storeNext Value (Ptr a)
p (T a -> CodeGenFunction () (Value (Ptr a)))
-> CodeGenFunction () (T a) -> CodeGenFunction () (Value (Ptr a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Val (Index sh) -> CodeGenFunction () (T a)
forall r. Val (Index sh) -> Code r a
code T ix
Val (Index sh)
ix
         T sh
sh <- Exp sh -> Value (MarshalPtr sh) -> CodeGenFunction () (T sh)
forall sh (f :: * -> *) r.
C sh =>
f sh -> Value (Ptr (Struct sh)) -> CodeGenFunction r (T sh)
Shape.load Exp sh
esh Value (MarshalPtr sh)
shapePtr
         CodeGenFunction () (Value (Ptr a)) -> CodeGenFunction () ()
forall (m :: * -> *) a. Monad m => m a -> m ()
void (CodeGenFunction () (Value (Ptr a)) -> CodeGenFunction () ())
-> CodeGenFunction () (Value (Ptr a)) -> CodeGenFunction () ()
forall a b. (a -> b) -> a -> b
$ (T ix -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a)))
-> T sh -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a))
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
Shape.loop T ix -> Value (Ptr a) -> CodeGenFunction () (Value (Ptr a))
step T sh
sh Value (Ptr a)
bufferPtr)


data Scatter sh0 sh1 a =
   Scatter {
      forall sh0 sh1 a. Scatter sh0 sh1 a -> Exp a -> Exp a -> Exp a
scatterAccum :: Exp a -> Exp a -> Exp a,
      forall sh0 sh1 a. Scatter sh0 sh1 a -> Array sh1 a
scatterInit :: Core.Array sh1 a,
      forall sh0 sh1 a. Scatter sh0 sh1 a -> Array sh0 (Index sh1, a)
scatterMap :: Core.Array sh0 (Shape.Index sh1, a)
   }

scatter ::
   (Shape.C sh0, Shape.Index sh0 ~ ix0,
    Shape.C sh1, Shape.Index sh1 ~ ix1, Marshal.C sh1,
    Storable.C a) =>
   Sym.Hull p (Scatter sh0 sh1 a) -> IO (p -> IO (Array sh1 a))
scatter :: forall sh0 ix0 sh1 ix1 a p.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C a) =>
Hull p (Scatter sh0 sh1 a) -> IO (p -> IO (Array sh1 a))
scatter =
   String
-> (Scatter sh0 sh1 a -> Exp sh1)
-> (Scatter sh0 sh1 a
    -> Value (MarshalPtr sh1)
    -> Value (Ptr a)
    -> CodeGenFunction () ())
-> Hull p (Scatter sh0 sh1 a)
-> IO (p -> IO (Array sh1 a))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"scatter"
      (Array sh1 a -> Exp sh1
forall sh a. Array sh a -> Exp sh
Core.shape (Array sh1 a -> Exp sh1)
-> (Scatter sh0 sh1 a -> Array sh1 a)
-> Scatter sh0 sh1 a
-> Exp sh1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scatter sh0 sh1 a -> Array sh1 a
forall sh0 sh1 a. Scatter sh0 sh1 a -> Array sh1 a
scatterInit)
      (\(Scatter Exp a -> Exp a -> Exp a
accum Array sh1 a
arrInit Array sh0 (Index sh1, a)
arrMap) ->
         (Exp a -> Exp a -> Exp a)
-> Array sh1 a
-> Array sh0 (Index sh1, a)
-> Value (MarshalPtr sh1)
-> Value (Ptr a)
-> CodeGenFunction () ()
forall sh0 ix0 sh1 ix1 a r.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C a) =>
(Exp a -> Exp a -> Exp a)
-> Array sh1 a
-> Array sh0 (Index sh1, a)
-> Value (MarshalPtr sh1)
-> Value (Ptr a)
-> CodeGenFunction r ()
Priv.scatter Exp a -> Exp a -> Exp a
accum Array sh1 a
arrInit Array sh0 (Index sh1, a)
arrMap)



data ScatterMaybe sh0 sh1 a =
   ScatterMaybe {
      forall sh0 sh1 a. ScatterMaybe sh0 sh1 a -> Exp a -> Exp a -> Exp a
scatterMaybeAccum :: Exp a -> Exp a -> Exp a,
      forall sh0 sh1 a. ScatterMaybe sh0 sh1 a -> Array sh1 a
scatterMaybeInit :: Core.Array sh1 a,
      forall sh0 sh1 a.
ScatterMaybe sh0 sh1 a -> Array sh0 (Maybe (Index sh1, a))
scatterMaybeMap :: Core.Array sh0 (Maybe (Shape.Index sh1, a))
   }

scatterMaybe ::
   (Shape.C sh0, Shape.Index sh0 ~ ix0,
    Shape.C sh1, Shape.Index sh1 ~ ix1, Marshal.C sh1,
    Storable.C a) =>
   Sym.Hull p (ScatterMaybe sh0 sh1 a) -> IO (p -> IO (Array sh1 a))
scatterMaybe :: forall sh0 ix0 sh1 ix1 a p.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C a) =>
Hull p (ScatterMaybe sh0 sh1 a) -> IO (p -> IO (Array sh1 a))
scatterMaybe =
   String
-> (ScatterMaybe sh0 sh1 a -> Exp sh1)
-> (ScatterMaybe sh0 sh1 a
    -> Value (MarshalPtr sh1)
    -> Value (Ptr a)
    -> CodeGenFunction () ())
-> Hull p (ScatterMaybe sh0 sh1 a)
-> IO (p -> IO (Array sh1 a))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"scatterMaybe"
      (Array sh1 a -> Exp sh1
forall sh a. Array sh a -> Exp sh
Core.shape (Array sh1 a -> Exp sh1)
-> (ScatterMaybe sh0 sh1 a -> Array sh1 a)
-> ScatterMaybe sh0 sh1 a
-> Exp sh1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScatterMaybe sh0 sh1 a -> Array sh1 a
forall sh0 sh1 a. ScatterMaybe sh0 sh1 a -> Array sh1 a
scatterMaybeInit)
      (\(ScatterMaybe Exp a -> Exp a -> Exp a
accum Array sh1 a
arrInit Array sh0 (Maybe (Index sh1, a))
arrMap) ->
         (Exp a -> Exp a -> Exp a)
-> Array sh1 a
-> Array sh0 (Maybe (ix1, a))
-> Value (MarshalPtr sh1)
-> Value (Ptr a)
-> CodeGenFunction () ()
forall sh0 ix0 sh1 ix1 a r.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh1, C a) =>
(Exp a -> Exp a -> Exp a)
-> Array sh1 a
-> Array sh0 (Maybe (ix1, a))
-> Value (MarshalPtr sh1)
-> Value (Ptr a)
-> CodeGenFunction r ()
Priv.scatterMaybe Exp a -> Exp a -> Exp a
accum Array sh1 a
arrInit Array sh0 (Maybe (ix1, a))
Array sh0 (Maybe (Index sh1, a))
arrMap)


data MapAccumLSimple sh n acc a b =
   MapAccumLSimple {
      forall sh n acc a b.
MapAccumLSimple sh n acc a b -> Exp acc -> Exp a -> Exp (acc, b)
mapAccumLSimpleAccum :: Exp acc -> Exp a -> Exp (acc,b),
      forall sh n acc a b. MapAccumLSimple sh n acc a b -> Array sh acc
mapAccumLSimpleInit :: Core.Array sh acc,
      forall sh n acc a b.
MapAccumLSimple sh n acc a b -> Array (sh, n) a
mapAccumLSimpleArray :: Core.Array (sh, n) a
   }

mapAccumLSimple ::
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    MultiValue.C acc, Storable.C a, Storable.C b) =>
   Sym.Hull p (MapAccumLSimple sh n acc a b) -> IO (p -> IO (Array (sh,n) b))
mapAccumLSimple :: forall sh n acc a b p.
(C sh, C sh, C n, C n, C acc, C a, C b) =>
Hull p (MapAccumLSimple sh n acc a b)
-> IO (p -> IO (Array (sh, n) b))
mapAccumLSimple =
   String
-> (MapAccumLSimple sh n acc a b -> Exp (sh, n))
-> (MapAccumLSimple sh n acc a b
    -> Value (MarshalPtr (sh, n))
    -> Value (Ptr b)
    -> CodeGenFunction () ())
-> Hull p (MapAccumLSimple sh n acc a b)
-> IO (p -> IO (Array (sh, n) b))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"mapAccumLSimple"
      (Array (sh, n) a -> Exp (sh, n)
forall sh a. Array sh a -> Exp sh
Core.shape (Array (sh, n) a -> Exp (sh, n))
-> (MapAccumLSimple sh n acc a b -> Array (sh, n) a)
-> MapAccumLSimple sh n acc a b
-> Exp (sh, n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MapAccumLSimple sh n acc a b -> Array (sh, n) a
forall sh n acc a b.
MapAccumLSimple sh n acc a b -> Array (sh, n) a
mapAccumLSimpleArray)
      (\(MapAccumLSimple Exp acc -> Exp a -> Exp (acc, b)
f Array sh acc
arrInit Array (sh, n) a
arrData) ->
         (Exp acc -> Exp a -> Exp (acc, b))
-> Array sh acc
-> Array (sh, n) a
-> Value (MarshalPtr (sh, n))
-> Value (Ptr b)
-> CodeGenFunction () ()
forall sh n acc x y r.
(C sh, C sh, C n, C n, C acc, C x, C y) =>
(Exp acc -> Exp x -> Exp (acc, y))
-> Array sh acc
-> Array (sh, n) x
-> Value (MarshalPtr (sh, n))
-> Value (Ptr y)
-> CodeGenFunction r ()
Priv.mapAccumLSimple Exp acc -> Exp a -> Exp (acc, b)
f Array sh acc
arrInit Array (sh, n) a
arrData)


data MapAccumLSequence n acc final a b =
   MapAccumLSequence {
      forall n acc final a b.
MapAccumLSequence n acc final a b
-> Exp acc -> Exp a -> Exp (acc, b)
mapAccumLSequenceAccum :: Exp acc -> Exp a -> Exp (acc,b),
      forall n acc final a b.
MapAccumLSequence n acc final a b -> Exp acc -> Exp final
mapAccumLSequenceFinal :: Exp acc -> Exp final,
      forall n acc final a b.
MapAccumLSequence n acc final a b -> Exp acc
mapAccumLSequenceInit :: Exp acc,
      forall n acc final a b.
MapAccumLSequence n acc final a b -> Array n a
mapAccumLSequenceArray :: Core.Array n a
   }

-- FIXME: check correct size of array of initial values
mapAccumLSequence ::
   (Shape.C n, Marshal.C n, MultiValue.C acc,
    Storable.C final, MultiValue.C final,
    Storable.C a, Storable.C b) =>
   Sym.Hull p (MapAccumLSequence n acc final a b) ->
   IO (p -> IO (final, Array n b))
mapAccumLSequence :: forall n acc final a b p.
(C n, C n, C acc, C final, C final, C a, C b) =>
Hull p (MapAccumLSequence n acc final a b)
-> IO (p -> IO (final, Array n b))
mapAccumLSequence =
   String
-> (MapAccumLSequence n acc final a b -> Exp n)
-> (MapAccumLSequence n acc final a b
    -> Value (Ptr final)
    -> Value (MarshalPtr n)
    -> Value (Ptr b)
    -> CodeGenFunction () ())
-> Hull p (MapAccumLSequence n acc final a b)
-> IO (p -> IO (final, Array n b))
forall sh a b core p.
(C sh, C sh, C a, C b) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (Ptr b)
    -> Value (MarshalPtr sh)
    -> Value (Ptr a)
    -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (b, Array sh a))
materializeExpArray String
"mapAccumLSequence"
      (Array n a -> Exp n
forall sh a. Array sh a -> Exp sh
Core.shape (Array n a -> Exp n)
-> (MapAccumLSequence n acc final a b -> Array n a)
-> MapAccumLSequence n acc final a b
-> Exp n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MapAccumLSequence n acc final a b -> Array n a
forall n acc final a b.
MapAccumLSequence n acc final a b -> Array n a
mapAccumLSequenceArray)
      (\(MapAccumLSequence Exp acc -> Exp a -> Exp (acc, b)
f Exp acc -> Exp final
final Exp acc
expInit Array n a
arr) ->
         (Exp acc -> Exp a -> Exp (acc, b))
-> (Exp acc -> Exp final)
-> Exp acc
-> Array n a
-> Value (Ptr final)
-> Value (MarshalPtr n)
-> Value (Ptr b)
-> CodeGenFunction () ()
forall n acc final x y r.
(C n, C n, C acc, C final, C x, C y) =>
(Exp acc -> Exp x -> Exp (acc, y))
-> (Exp acc -> Exp final)
-> Exp acc
-> Array n x
-> Value (Ptr final)
-> Value (MarshalPtr n)
-> Value (Ptr y)
-> CodeGenFunction r ()
Priv.mapAccumLSequence Exp acc -> Exp a -> Exp (acc, b)
f Exp acc -> Exp final
final Exp acc
expInit Array n a
arr)


data MapAccumL sh n acc final a b =
   MapAccumL {
      forall sh n acc final a b.
MapAccumL sh n acc final a b -> Exp acc -> Exp a -> Exp (acc, b)
mapAccumLAccum :: Exp acc -> Exp a -> Exp (acc,b),
      forall sh n acc final a b.
MapAccumL sh n acc final a b -> Exp acc -> Exp final
mapAccumLFinal :: Exp acc -> Exp final,
      forall sh n acc final a b.
MapAccumL sh n acc final a b -> Array sh acc
mapAccumLInit :: Core.Array sh acc,
      forall sh n acc final a b.
MapAccumL sh n acc final a b -> Array (sh, n) a
mapAccumLArray :: Core.Array (sh, n) a
   }

-- FIXME: check correct size of array of initial values
mapAccumL ::
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    MultiValue.C acc,
    Storable.C final, MultiValue.C final,
    Storable.C a, Storable.C b) =>
   Sym.Hull p (MapAccumL sh n acc final a b) ->
   IO (p -> IO (Array sh final, Array (sh,n) b))
mapAccumL :: forall sh n acc final a b p.
(C sh, C sh, C n, C n, C acc, C final, C final, C a, C b) =>
Hull p (MapAccumL sh n acc final a b)
-> IO (p -> IO (Array sh final, Array (sh, n) b))
mapAccumL =
   String
-> (MapAccumL sh n acc final a b -> Exp (sh, (sh, n)))
-> (MapAccumL sh n acc final a b
    -> (Value (MarshalPtr sh), Value (Ptr final))
    -> (Value (MarshalPtr (sh, n)), Value (Ptr b))
    -> CodeGenFunction () ())
-> Hull p (MapAccumL sh n acc final a b)
-> IO (p -> IO (Array sh final, Array (sh, n) b))
forall sha shb a b core p.
(C sha, C sha, C shb, C shb, C a, C b) =>
String
-> (core -> Exp (sha, shb))
-> (core
    -> (Value (MarshalPtr sha), Value (Ptr a))
    -> (Value (MarshalPtr shb), Value (Ptr b))
    -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sha a, Array shb b))
materialize2 String
"mapAccumL"
      (\MapAccumL sh n acc final a b
core ->
         Exp sh -> Exp (sh, n) -> Exp (sh, (sh, n))
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip
            (Array sh acc -> Exp sh
forall sh a. Array sh a -> Exp sh
Core.shape (Array sh acc -> Exp sh) -> Array sh acc -> Exp sh
forall a b. (a -> b) -> a -> b
$ MapAccumL sh n acc final a b -> Array sh acc
forall sh n acc final a b.
MapAccumL sh n acc final a b -> Array sh acc
mapAccumLInit MapAccumL sh n acc final a b
core)
            (Array (sh, n) a -> Exp (sh, n)
forall sh a. Array sh a -> Exp sh
Core.shape (Array (sh, n) a -> Exp (sh, n)) -> Array (sh, n) a -> Exp (sh, n)
forall a b. (a -> b) -> a -> b
$ MapAccumL sh n acc final a b -> Array (sh, n) a
forall sh n acc final a b.
MapAccumL sh n acc final a b -> Array (sh, n) a
mapAccumLArray MapAccumL sh n acc final a b
core))
      (\(MapAccumL Exp acc -> Exp a -> Exp (acc, b)
f Exp acc -> Exp final
final Array sh acc
arrInit Array (sh, n) a
arrData) ->
         (Exp acc -> Exp a -> Exp (acc, b))
-> (Exp acc -> Exp final)
-> Array sh acc
-> Array (sh, n) a
-> (Value (MarshalPtr sh), Value (Ptr final))
-> (Value (MarshalPtr (sh, n)), Value (Ptr b))
-> CodeGenFunction () ()
forall sh n acc final x y r.
(C sh, C sh, C n, C n, C acc, C final, C x, C y) =>
(Exp acc -> Exp x -> Exp (acc, y))
-> (Exp acc -> Exp final)
-> Array sh acc
-> Array (sh, n) x
-> (Value (MarshalPtr sh), Value (Ptr final))
-> (Value (MarshalPtr (sh, n)), Value (Ptr y))
-> CodeGenFunction r ()
Priv.mapAccumL Exp acc -> Exp a -> Exp (acc, b)
f Exp acc -> Exp final
final Array sh acc
arrInit Array (sh, n) a
arrData)


data FoldOuterL n sh a b =
   FoldOuterL {
      forall n sh a b. FoldOuterL n sh a b -> Exp a -> Exp b -> Exp a
foldOuterLAccum :: Exp a -> Exp b -> Exp a,
      forall n sh a b. FoldOuterL n sh a b -> Array sh a
foldOuterLInit :: Core.Array sh a,
      forall n sh a b. FoldOuterL n sh a b -> Array (n, sh) b
foldOuterLArray :: Core.Array (n,sh) b
   }

-- FIXME: check correct size of array of initial values
foldOuterL ::
   (Shape.C n, Marshal.C n,
    Shape.C sh, Marshal.C sh,
    Storable.C a) =>
   Sym.Hull p (FoldOuterL n sh a b) -> IO (p -> IO (Array sh a))
foldOuterL :: forall n sh a p b.
(C n, C n, C sh, C sh, C a) =>
Hull p (FoldOuterL n sh a b) -> IO (p -> IO (Array sh a))
foldOuterL =
   String
-> (FoldOuterL n sh a b -> Exp sh)
-> (FoldOuterL n sh a b
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p (FoldOuterL n sh a b)
-> IO (p -> IO (Array sh a))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"foldOuterL"
      (Array sh a -> Exp sh
forall sh a. Array sh a -> Exp sh
Core.shape (Array sh a -> Exp sh)
-> (FoldOuterL n sh a b -> Array sh a)
-> FoldOuterL n sh a b
-> Exp sh
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FoldOuterL n sh a b -> Array sh a
forall n sh a b. FoldOuterL n sh a b -> Array sh a
foldOuterLInit)
      (\(FoldOuterL Exp a -> Exp b -> Exp a
f Array sh a
arrInit Array (n, sh) b
arrData) -> (Exp a -> Exp b -> Exp a)
-> Array sh a
-> Array (n, sh) b
-> Value (MarshalPtr sh)
-> Value (Ptr a)
-> CodeGenFunction () ()
forall sh n a b r.
(C sh, C sh, C n, C n, C a) =>
(Exp a -> Exp b -> Exp a)
-> Array sh a
-> Array (n, sh) b
-> Value (MarshalPtr sh)
-> Value (Ptr a)
-> CodeGenFunction r ()
Priv.foldOuterL Exp a -> Exp b -> Exp a
f Array sh a
arrInit Array (n, sh) b
arrData)


data MapFilter n a b =
   MapFilter {
      forall n a b. MapFilter n a b -> Exp a -> Exp b
mapFilterMap :: Exp a -> Exp b,
      forall n a b. MapFilter n a b -> Exp a -> Exp Bool
mapFilterPredicate :: Exp a -> Exp Bool,
      forall n a b. MapFilter n a b -> Array n a
mapFilterArray :: Core.Array n a
   }

mapFilter ::
   (Shape.Sequence n, Marshal.C n, Storable.C b) =>
   Sym.Hull p (MapFilter n a b) -> IO (p -> IO (Array n b))
mapFilter :: forall n b p a.
(Sequence n, C n, C b) =>
Hull p (MapFilter n a b) -> IO (p -> IO (Array n b))
mapFilter =
   String
-> (MapFilter n a b -> Exp n)
-> (MapFilter n a b
    -> Value (MarshalPtr n) -> Value (Ptr b) -> CodeGenFunction () ())
-> Hull p (MapFilter n a b)
-> IO (p -> IO (Array n b))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"mapFilter"
      (Array n a -> Exp n
forall sh a. Array sh a -> Exp sh
Core.shape (Array n a -> Exp n)
-> (MapFilter n a b -> Array n a) -> MapFilter n a b -> Exp n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MapFilter n a b -> Array n a
forall n a b. MapFilter n a b -> Array n a
mapFilterArray)
      (\(MapFilter Exp a -> Exp b
f Exp a -> Exp Bool
p Array n a
arr) Value (MarshalPtr n)
shapePtr Value (Ptr b)
bufferPtr ->
         (T n -> Value (MarshalPtr n) -> CodeGenFunction () ())
-> Value (MarshalPtr n) -> T n -> CodeGenFunction () ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip T n -> Value (MarshalPtr n) -> CodeGenFunction () ()
T n -> Value (Ptr (Struct (T n))) -> CodeGenFunction () ()
forall r. T n -> Value (Ptr (Struct (T n))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store Value (MarshalPtr n)
shapePtr
            (T n -> CodeGenFunction () ())
-> CodeGenFunction () (T n) -> CodeGenFunction () ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Exp a -> Exp b)
-> (Exp a -> Exp Bool)
-> Array n a
-> Value (MarshalPtr n)
-> Value (Ptr b)
-> CodeGenFunction () (T n)
forall n b a r.
(Sequence n, C n, C b) =>
(Exp a -> Exp b)
-> (Exp a -> Exp Bool)
-> Array n a
-> Value (MarshalPtr n)
-> Value (Ptr b)
-> CodeGenFunction r (T n)
Priv.mapFilter Exp a -> Exp b
f Exp a -> Exp Bool
p Array n a
arr Value (MarshalPtr n)
shapePtr Value (Ptr b)
bufferPtr)


data FilterOuter n sh a =
   FilterOuter {
      forall n sh a. FilterOuter n sh a -> Array n Bool
filterOuterPredicate :: Core.Array n Bool,
      forall n sh a. FilterOuter n sh a -> Array (n, sh) a
filterOuterArray :: Core.Array (n,sh) a
   }

-- FIXME: check correct size of row selection array
filterOuter ::
   (Shape.Sequence n, Marshal.C n,
    Shape.C sh, Marshal.C sh,
    Storable.C a) =>
   Sym.Hull p (FilterOuter n sh a) -> IO (p -> IO (Array (n,sh) a))
filterOuter :: forall n sh a p.
(Sequence n, C n, C sh, C sh, C a) =>
Hull p (FilterOuter n sh a) -> IO (p -> IO (Array (n, sh) a))
filterOuter =
   String
-> (FilterOuter n sh a -> Exp (n, sh))
-> (FilterOuter n sh a
    -> Value (MarshalPtr (n, sh))
    -> Value (Ptr a)
    -> CodeGenFunction () ())
-> Hull p (FilterOuter n sh a)
-> IO (p -> IO (Array (n, sh) a))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"filterOuter"
      (Array (n, sh) a -> Exp (n, sh)
forall sh a. Array sh a -> Exp sh
Core.shape (Array (n, sh) a -> Exp (n, sh))
-> (FilterOuter n sh a -> Array (n, sh) a)
-> FilterOuter n sh a
-> Exp (n, sh)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilterOuter n sh a -> Array (n, sh) a
forall n sh a. FilterOuter n sh a -> Array (n, sh) a
filterOuterArray)
      (\(FilterOuter Array n Bool
p Array (n, sh) a
arr) Value (MarshalPtr (n, sh))
shapePtr Value (Ptr a)
bufferPtr ->
         (T (n, sh)
 -> Value (Ptr (Struct (Struct (Repr n), (Struct (Repr sh), ()))))
 -> CodeGenFunction () ())
-> Value (Ptr (Struct (Struct (Repr n), (Struct (Repr sh), ()))))
-> T (n, sh)
-> CodeGenFunction () ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip T (n, sh)
-> Value (Ptr (Struct (T (n, sh)))) -> CodeGenFunction () ()
T (n, sh)
-> Value (Ptr (Struct (Struct (Repr n), (Struct (Repr sh), ()))))
-> CodeGenFunction () ()
forall r.
T (n, sh)
-> Value (Ptr (Struct (T (n, sh)))) -> CodeGenFunction r ()
forall llvmValue r.
C llvmValue =>
llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
Memory.store Value (MarshalPtr (n, sh))
Value (Ptr (Struct (Struct (Repr n), (Struct (Repr sh), ()))))
shapePtr
            (T (n, sh) -> CodeGenFunction () ())
-> CodeGenFunction () (T (n, sh)) -> CodeGenFunction () ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Array n Bool
-> Array (n, sh) a
-> Value (MarshalPtr (n, sh))
-> Value (Ptr a)
-> CodeGenFunction () (T (n, sh))
forall n sh a r.
(Sequence n, C n, C sh, C sh, C a) =>
Array n Bool
-> Array (n, sh) a
-> Value (MarshalPtr (n, sh))
-> Value (Ptr a)
-> CodeGenFunction r (T (n, sh))
Priv.filterOuter Array n Bool
p Array (n, sh) a
arr Value (MarshalPtr (n, sh))
shapePtr Value (Ptr a)
bufferPtr)


data AddDimension sh n a b =
   AddDimension {
      forall sh n a b. AddDimension sh n a b -> Exp n
addDimensionSize :: Exp n,
      forall sh n a b.
AddDimension sh n a b -> Exp (Index n) -> Exp a -> Exp b
addDimensionSelect :: Exp (Shape.Index n) -> Exp a -> Exp b,
      forall sh n a b. AddDimension sh n a b -> Array sh a
addDimensionArray :: Core.Array sh a
   }

addDimension ::
   (Shape.C sh, Marshal.C sh,
    Shape.C n, Marshal.C n,
    Storable.C b) =>
   Sym.Hull p (AddDimension sh n a b) -> IO (p -> IO (Array (sh,n) b))
addDimension :: forall sh n b p a.
(C sh, C sh, C n, C n, C b) =>
Hull p (AddDimension sh n a b) -> IO (p -> IO (Array (sh, n) b))
addDimension =
   String
-> (AddDimension sh n a b -> Exp (sh, n))
-> (AddDimension sh n a b
    -> Value (MarshalPtr (sh, n))
    -> Value (Ptr b)
    -> CodeGenFunction () ())
-> Hull p (AddDimension sh n a b)
-> IO (p -> IO (Array (sh, n) b))
forall sh a core p.
(C sh, C sh, C a) =>
String
-> (core -> Exp sh)
-> (core
    -> Value (MarshalPtr sh) -> Value (Ptr a) -> CodeGenFunction () ())
-> Hull p core
-> IO (p -> IO (Array sh a))
materialize String
"addDimension"
      (\AddDimension sh n a b
r -> Exp sh -> Exp n -> Exp (sh, n)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip (Array sh a -> Exp sh
forall sh a. Array sh a -> Exp sh
Core.shape (AddDimension sh n a b -> Array sh a
forall sh n a b. AddDimension sh n a b -> Array sh a
addDimensionArray AddDimension sh n a b
r)) (AddDimension sh n a b -> Exp n
forall sh n a b. AddDimension sh n a b -> Exp n
addDimensionSize AddDimension sh n a b
r))
      (\(AddDimension Exp n
n Exp (Index n) -> Exp a -> Exp b
select Array sh a
arr) -> Exp n
-> (Exp (Index n) -> Exp a -> Exp b)
-> Array sh a
-> Value (MarshalPtr (sh, n))
-> Value (Ptr b)
-> CodeGenFunction () ()
forall n k sh b a r.
(C n, C n, Index n ~ k, C sh, C sh, C b) =>
Exp n
-> (Exp k -> Exp a -> Exp b)
-> Array sh a
-> Value (MarshalPtr (sh, n))
-> Value (Ptr b)
-> CodeGenFunction r ()
Priv.addDimension Exp n
n Exp (Index n) -> Exp a -> Exp b
select Array sh a
arr)