-- GENERATED by C->Haskell Compiler, version 0.28.6 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TemplateHaskell          #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Graph.Exec
-- Copyright : [2018] Trevor L. McDonell
-- License   : BSD
--
-- Graph execution functions for the low-level driver interface
--
-- Requires CUDA-10
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Graph.Exec (

  Executable(..),

  -- ** Execution
  launch,
  instantiate,
  destroy,
  setKernel,

) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp





{-# LINE 30 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}


import Foreign.CUDA.Driver.Error
import Foreign.CUDA.Driver.Exec                           ( Fun(..), FunParam(..) )
import Foreign.CUDA.Driver.Graph.Base
import Foreign.CUDA.Driver.Stream                         ( Stream(..) )
import Foreign.CUDA.Internal.C2HS

import Foreign
import Foreign.C

import Control.Monad                                      ( liftM )
import Data.ByteString.Char8                              ( ByteString )
import qualified Data.ByteString.Char8                    as B
import qualified Data.ByteString.Internal                 as B


--------------------------------------------------------------------------------
-- Graph execution
--------------------------------------------------------------------------------

-- | Execute a graph in the given stream. Only one instance may execute at
-- a time; to execute a graph concurrently, it must be 'instantiate'd into
-- multiple executables.
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__GRAPH.html#group__CUDA__GRAPH_1g6b2dceb3901e71a390d2bd8b0491e471>
--
-- @since 0.10.0.0
--
{-# INLINEABLE launch #-}
launch :: (Executable) -> (Stream) -> IO ()
launch :: Executable -> Stream -> IO ()
launch Executable
a1 Stream
a2 =
  let {a1' :: Ptr ()
a1' = Executable -> Ptr ()
useExecutable Executable
a1} in 
  let {a2' :: Ptr ()
a2' = Stream -> Ptr ()
useStream Stream
a2} in 
  Ptr () -> Ptr () -> IO CInt
launch'_ Ptr ()
a1' Ptr ()
a2' IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 71 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}



-- | Instantiate the task graph description of a program into an executable
-- graph.
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__GRAPH.html#group__CUDA__GRAPH_1g433ae118a751c9f2087f53d7add7bc2c>
--
-- @since 0.10.0.0
--
{-# INLINEABLE instantiate #-}
instantiate :: Graph -> IO Executable
instantiate :: Graph -> IO Executable
instantiate !Graph
g = do
  let logSize :: Int
logSize = Int
2048
  Int -> (Ptr CChar -> IO Executable) -> IO Executable
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
logSize ((Ptr CChar -> IO Executable) -> IO Executable)
-> (Ptr CChar -> IO Executable) -> IO Executable
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
p_elog -> do
    (Status
s, Executable
e, Maybe Node
n) <- Graph -> Ptr CChar -> Int -> IO (Status, Executable, Maybe Node)
cuGraphInstantiate Graph
g Ptr CChar
p_elog Int
logSize
    --
    case Status
s of
      Status
Success -> Executable -> IO Executable
forall (m :: * -> *) a. Monad m => a -> m a
return Executable
e
      Status
_       -> do
        String
errLog <- CStringLen -> IO String
peekCStringLen (Ptr CChar
p_elog, Int
logSize)
        String -> IO Executable
forall a. String -> IO a
cudaErrorIO ([String] -> String
unlines [Status -> String
forall a. Describe a => a -> String
describe Status
s, String
"phErrorNode = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Node -> String
forall a. Show a => a -> String
show Maybe Node
n, String
errLog])

{-# INLINE cuGraphInstantiate #-}
cuGraphInstantiate :: (Graph) -> (CString) -> (Int) -> IO ((Status), (Executable), (Maybe Node))
cuGraphInstantiate :: Graph -> Ptr CChar -> Int -> IO (Status, Executable, Maybe Node)
cuGraphInstantiate Graph
a2 Ptr CChar
a4 Int
a5 =
  (Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
 -> IO (Status, Executable, Maybe Node))
-> (Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr ())
a1' -> 
  let {a2' :: Ptr ()
a2' = Graph -> Ptr ()
useGraph Graph
a2} in 
  (Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
 -> IO (Status, Executable, Maybe Node))
-> (Ptr (Ptr ()) -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr ())
a3' -> 
  let {a4' :: Ptr b
a4' = Ptr CChar -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
a4} in 
  let {a5' :: CULong
a5' = Int -> CULong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a5} in 
  Ptr (Ptr ())
-> Ptr () -> Ptr (Ptr ()) -> Ptr CChar -> CULong -> IO CInt
cuGraphInstantiate'_ Ptr (Ptr ())
a1' Ptr ()
a2' Ptr (Ptr ())
a3' Ptr CChar
forall b. Ptr b
a4' CULong
a5' IO CInt
-> (CInt -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  let {res' :: Status
res' = CInt -> Status
forall i e. (Integral i, Enum e) => i -> e
cToEnum CInt
res} in
  Ptr (Ptr ()) -> IO Executable
peekExecutable  Ptr (Ptr ())
a1'IO Executable
-> (Executable -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Executable
a1'' -> 
  Ptr (Ptr ()) -> IO (Maybe Node)
peekErrNode  Ptr (Ptr ())
a3'IO (Maybe Node)
-> (Maybe Node -> IO (Status, Executable, Maybe Node))
-> IO (Status, Executable, Maybe Node)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Maybe Node
a3'' -> 
  (Status, Executable, Maybe Node)
-> IO (Status, Executable, Maybe Node)
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
res', Executable
a1'', Maybe Node
a3'')

{-# LINE 107 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}

  where
    peekExecutable  = liftM Executable . peek
    peekErrNode p   = if p == nullPtr
                        then return Nothing
                        else liftM (Just . Node) (peek p)


-- | Update the parameters for a kernel node in the given executable graph
--
-- Requires CUDA-10.1
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__GRAPH.html#group__CUDA__GRAPH_1gd84243569e4c3d6356b9f2eea20ed48c>
--
-- @since 0.10.1.0
--
setKernel
    :: Executable
    -> Node
    -> Fun
    -> (Int, Int, Int)  -- ^ grid dimension
    -> (Int, Int, Int)  -- ^ thread block dimensions
    -> Int              -- ^ shared memory (bytes)
    -> [FunParam]
    -> IO ()
setKernel :: Executable
-> Node
-> Fun
-> (Int, Int, Int)
-> (Int, Int, Int)
-> Int
-> [FunParam]
-> IO ()
setKernel !Executable
exe !Node
n !Fun
fun (!Int
gx,!Int
gy,!Int
gz) (!Int
tx,!Int
ty,!Int
tz) !Int
sm ![FunParam]
args
  = (FunParam -> (Ptr () -> IO ()) -> IO ())
-> [FunParam] -> ([Ptr ()] -> IO ()) -> IO ()
forall a b res.
(a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
withMany FunParam -> (Ptr () -> IO ()) -> IO ()
forall b. FunParam -> (Ptr () -> IO b) -> IO b
withFP [FunParam]
args
  (([Ptr ()] -> IO ()) -> IO ()) -> ([Ptr ()] -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \[Ptr ()]
pa -> [Ptr ()] -> (Ptr (Ptr ()) -> IO ()) -> IO ()
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [Ptr ()]
pa
  ((Ptr (Ptr ()) -> IO ()) -> IO ())
-> (Ptr (Ptr ()) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr ())
pp -> Executable
-> Node
-> Fun
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> Ptr (Ptr ())
-> IO ()
cuGraphExecKernelNodeSetParams_simple Executable
exe Node
n Fun
fun Int
gx Int
gy Int
gz Int
tx Int
ty Int
tz Int
sm Ptr (Ptr ())
pp
  where
    withFP :: FunParam -> (Ptr () -> IO b) -> IO b
    withFP :: FunParam -> (Ptr () -> IO b) -> IO b
withFP !FunParam
p !Ptr () -> IO b
f = case FunParam
p of
      IArg Int32
v -> Int32 -> (Ptr Int32 -> IO b) -> IO b
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with' Int32
v (Ptr () -> IO b
f (Ptr () -> IO b) -> (Ptr Int32 -> Ptr ()) -> Ptr Int32 -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Int32 -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr)
      FArg Float
v -> Float -> (Ptr Float -> IO b) -> IO b
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with' Float
v (Ptr () -> IO b
f (Ptr () -> IO b) -> (Ptr Float -> Ptr ()) -> Ptr Float -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Float -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr)
      VArg a
v -> a -> (Ptr a -> IO b) -> IO b
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with' a
v (Ptr () -> IO b
f (Ptr () -> IO b) -> (Ptr a -> Ptr ()) -> Ptr a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr)

    -- can't use the standard 'with' because 'alloca' will pass an undefined
    -- dummy argument when determining 'sizeOf' and 'alignment', but sometimes
    -- instances in Accelerate need to evaluate this argument.
    --
    with' :: Storable a => a -> (Ptr a -> IO b) -> IO b
    with' :: a -> (Ptr a -> IO b) -> IO b
with' !a
val !Ptr a -> IO b
f =
      Int -> (Ptr a -> IO b) -> IO b
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (a -> Int
forall a. Storable a => a -> Int
sizeOf a
val) ((Ptr a -> IO b) -> IO b) -> (Ptr a -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr a
ptr -> do
        Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
ptr a
val
        Ptr a -> IO b
f Ptr a
ptr

    cuGraphExecKernelNodeSetParams_simple :: (Executable) -> (Node) -> (Fun) -> (Int) -> (Int) -> (Int) -> (Int) -> (Int) -> (Int) -> (Int) -> (Ptr (Ptr ())) -> IO ()
    cuGraphExecKernelNodeSetParams_simple :: Executable
-> Node
-> Fun
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> Ptr (Ptr ())
-> IO ()
cuGraphExecKernelNodeSetParams_simple Executable
a1 Node
a2 Fun
a3 Int
a4 Int
a5 Int
a6 Int
a7 Int
a8 Int
a9 Int
a10 Ptr (Ptr ())
a11 =
      let {a1' :: Ptr ()
a1' = Executable -> Ptr ()
useExecutable Executable
a1} in 
      let {a2' :: Ptr ()
a2' = Node -> Ptr ()
useNode Node
a2} in 
      let {a3' :: Ptr ()
a3' = Fun -> Ptr ()
useFun Fun
a3} in 
      let {a4' :: CUInt
a4' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a4} in 
      let {a5' :: CUInt
a5' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a5} in 
      let {a6' :: CUInt
a6' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a6} in 
      let {a7' :: CUInt
a7' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a7} in 
      let {a8' :: CUInt
a8' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a8} in 
      let {a9' :: CUInt
a9' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a9} in 
      let {a10' :: CUInt
a10' = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a10} in 
      let {a11' :: Ptr (Ptr ())
a11' = Ptr (Ptr ()) -> Ptr (Ptr ())
forall a. a -> a
id Ptr (Ptr ())
a11} in 
      Ptr ()
-> Ptr ()
-> Ptr ()
-> CUInt
-> CUInt
-> CUInt
-> CUInt
-> CUInt
-> CUInt
-> CUInt
-> Ptr (Ptr ())
-> IO CInt
cuGraphExecKernelNodeSetParams_simple'_ Ptr ()
a1' Ptr ()
a2' Ptr ()
a3' CUInt
a4' CUInt
a5' CUInt
a6' CUInt
a7' CUInt
a8' CUInt
a9' CUInt
a10' Ptr (Ptr ())
a11' IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
      CInt -> IO ()
checkStatus CInt
res IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
      () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 171 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}



-- | Destroy an executable graph
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__GRAPH.html#group__CUDA__GRAPH_1ga32ad4944cc5d408158207c978bc43a7>
--
-- @since 0.10.0.0
--
{-# INLINEABLE destroy #-}
destroy :: (Executable) -> IO ()
destroy :: Executable -> IO ()
destroy Executable
a1 =
  let {a1' :: Ptr ()
a1' = Executable -> Ptr ()
useExecutable Executable
a1} in 
  Ptr () -> IO CInt
destroy'_ Ptr ()
a1' IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 191 "src/Foreign/CUDA/Driver/Graph/Exec.chs" #-}



foreign import ccall unsafe "Foreign/CUDA/Driver/Graph/Exec.chs.h cuGraphLaunch"
  launch'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))

foreign import ccall unsafe "Foreign/CUDA/Driver/Graph/Exec.chs.h cuGraphInstantiate"
  cuGraphInstantiate'_ :: ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CULong -> (IO C2HSImp.CInt))))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Graph/Exec.chs.h cuGraphExecKernelNodeSetParams_simple"
  cuGraphExecKernelNodeSetParams_simple'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CUInt -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO C2HSImp.CInt))))))))))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Graph/Exec.chs.h cuGraphExecDestroy"
  destroy'_ :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))