-- 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/Capture.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TemplateHaskell          #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Graph.Capture
-- Copyright : [2018] Trevor L. McDonell
-- License   : BSD
--
-- Requires CUDA-10
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Graph.Capture (

  Status(..), Mode(..),
  start, stop, status, info, mode,

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





{-# LINE 27 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}


import Foreign.CUDA.Driver.Error                          hiding ( Status )
import Foreign.CUDA.Driver.Graph.Base
import Foreign.CUDA.Driver.Stream
import Foreign.CUDA.Internal.C2HS

import Control.Monad                                      ( liftM )

import Foreign
import Foreign.C


data Status = None
            | Active
            | Invalidated
  deriving (Status -> Status -> Bool
(Status -> Status -> Bool)
-> (Status -> Status -> Bool) -> Eq Status
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Status -> Status -> Bool
$c/= :: Status -> Status -> Bool
== :: Status -> Status -> Bool
$c== :: Status -> Status -> Bool
Eq,Int -> Status -> ShowS
[Status] -> ShowS
Status -> String
(Int -> Status -> ShowS)
-> (Status -> String) -> ([Status] -> ShowS) -> Show Status
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Status] -> ShowS
$cshowList :: [Status] -> ShowS
show :: Status -> String
$cshow :: Status -> String
showsPrec :: Int -> Status -> ShowS
$cshowsPrec :: Int -> Status -> ShowS
Show,Status
Status -> Status -> Bounded Status
forall a. a -> a -> Bounded a
maxBound :: Status
$cmaxBound :: Status
minBound :: Status
$cminBound :: Status
Bounded)
instance Enum Status where
  succ :: Status -> Status
succ Status
None = Status
Active
  succ Status
Active = Status
Invalidated
  succ Status
Invalidated = String -> Status
forall a. HasCallStack => String -> a
error String
"Status.succ: Invalidated has no successor"

  pred :: Status -> Status
pred Status
Active = Status
None
  pred Status
Invalidated = Status
Active
  pred Status
None = String -> Status
forall a. HasCallStack => String -> a
error String
"Status.pred: None has no predecessor"

  enumFromTo :: Status -> Status -> [Status]
enumFromTo Status
from Status
to = Status -> [Status]
forall t. Enum t => t -> [t]
go Status
from
    where
      end = fromEnum to
      go v = case compare (fromEnum v) end of
                 LT -> v : go (succ v)
                 EQ -> [v]
                 GT -> []

  enumFrom from = enumFromTo from Invalidated

  fromEnum :: Status -> Int
fromEnum Status
None = Int
0
  fromEnum Status
Active = Int
1
  fromEnum Status
Invalidated = Int
2

  toEnum :: Int -> Status
toEnum Int
0 = Status
None
  toEnum Int
1 = Status
Active
  toEnum Int
2 = Status
Invalidated
  toEnum Int
unmatched = String -> Status
forall a. HasCallStack => String -> a
error (String
"Status.toEnum: Cannot match " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
unmatched)

{-# LINE 53 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}


data Mode = Global
          | ThreadLocal
          | Relaxed
  deriving (Eq,Show,Bounded)
instance Enum Mode where
  succ Global = ThreadLocal
  succ ThreadLocal = Relaxed
  succ Relaxed = error "Mode.succ: Relaxed has no successor"

  pred ThreadLocal = Global
  pred Relaxed = ThreadLocal
  pred Global = error "Mode.pred: Global has no predecessor"

  enumFromTo from to = go from
    where
      end = fromEnum to
      go v = case compare (fromEnum v) end of
                 LT -> v : go (succ v)
                 EQ -> [v]
                 GT -> []

  enumFrom :: Mode -> [Mode]
enumFrom Mode
from = Mode -> Mode -> [Mode]
forall a. Enum a => a -> a -> [a]
enumFromTo Mode
from Mode
Relaxed

  fromEnum :: Mode -> Int
fromEnum Mode
Global = Int
0
  fromEnum Mode
ThreadLocal = Int
1
  fromEnum Mode
Relaxed = Int
2

  toEnum :: Int -> Mode
toEnum Int
0 = Mode
Global
  toEnum 1 = ThreadLocal
  toEnum Int
2 = Mode
Relaxed
  toEnum Int
unmatched = String -> Mode
forall a. HasCallStack => String -> a
error (String
"Mode.toEnum: Cannot match " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
unmatched)

{-# LINE 68 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



--------------------------------------------------------------------------------
-- Graph capture
--------------------------------------------------------------------------------

-- | Begin graph capture on a stream
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1gea22d4496b1c8d02d0607bb05743532f>
--
-- @since 0.10.0.0
--
start :: (Stream) -> (Mode) -> IO ()
start a1 a2 =
  let {a1' = useStream a1} in 
  let {a2' = (fromIntegral . fromEnum) a2} in 
  start'_ a1' a2' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 100 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



-- | End graph capture on a stream
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1g03dab8b2ba76b00718955177a929970c>
--
-- @since 0.10.0.0
--
stop :: (Stream) -> IO ((Graph))
stop :: Stream -> IO Graph
stop Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  (Ptr (Ptr ()) -> IO Graph) -> IO Graph
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr ()) -> IO Graph) -> IO Graph)
-> (Ptr (Ptr ()) -> IO Graph) -> IO Graph
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr ())
a2' -> 
  Ptr () -> Ptr (Ptr ()) -> IO CInt
stop'_ Ptr ()
a1' Ptr (Ptr ())
a2' IO CInt -> (CInt -> IO Graph) -> IO Graph
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO Graph -> IO Graph
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  Ptr (Ptr ()) -> IO Graph
peekGraph  Ptr (Ptr ())
a2'IO Graph -> (Graph -> IO Graph) -> IO Graph
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Graph
a2'' -> 
  Graph -> IO Graph
forall (m :: * -> *) a. Monad m => a -> m a
return (Graph
a2'')

{-# LINE 120 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



-- | Return a stream's capture status
--
-- Requires CUDA-10.0
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1g37823c49206e3704ae23c7ad78560bca>
--
-- @since 0.10.0.0
--
status :: (Stream) -> IO ((Status))
status :: Stream -> IO Status
status Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  (Ptr CInt -> IO Status) -> IO Status
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO Status) -> IO Status)
-> (Ptr CInt -> IO Status) -> IO Status
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
a2' -> 
  Ptr () -> Ptr CInt -> IO CInt
status'_ Ptr ()
a1' Ptr CInt
a2' IO CInt -> (CInt -> IO Status) -> IO Status
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO Status -> IO Status
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  Ptr CInt -> IO Status
forall a b. (Enum a, Integral b, Storable b) => Ptr b -> IO a
peekEnum  Ptr CInt
a2'IO Status -> (Status -> IO Status) -> IO Status
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Status
a2'' -> 
  Status -> IO Status
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
a2'')

{-# LINE 140 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



-- | Query the capture status of a stream and get an id for the capture
-- sequence, which is unique over the lifetime of the process.
--
-- Requires CUDA-10.1
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1g13145ece1d79a1d79a1d22abb9663216>
--
-- @since 0.10.1.0
--
info :: (Stream) -> IO ((Status), (Int64))
info :: Stream -> IO (Status, Int64)
info Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  (Ptr CInt -> IO (Status, Int64)) -> IO (Status, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Status, Int64)) -> IO (Status, Int64))
-> (Ptr CInt -> IO (Status, Int64)) -> IO (Status, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
a2' -> 
  (Ptr CULLong -> IO (Status, Int64)) -> IO (Status, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CULLong -> IO (Status, Int64)) -> IO (Status, Int64))
-> (Ptr CULLong -> IO (Status, Int64)) -> IO (Status, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr CULLong
a3' -> 
  Ptr () -> Ptr CInt -> Ptr CULLong -> IO CInt
info'_ Ptr ()
a1' Ptr CInt
a2' Ptr CULLong
a3' IO CInt -> (CInt -> IO (Status, Int64)) -> IO (Status, Int64)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO Status -> IO Status
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  Ptr CInt -> IO Status
forall a b. (Enum a, Integral b, Storable b) => Ptr b -> IO a
peekEnum  Ptr CInt
a2'IO Status -> (Status -> IO (Status, Int64)) -> IO (Status, Int64)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Status
a2'' -> 
  Ptr CULLong -> IO Int64
forall a b. (Storable a, Integral a, Integral b) => Ptr a -> IO b
peekIntConv  Ptr CULLong
a3'IO Int64 -> (Int64 -> IO (Status, Int64)) -> IO (Status, Int64)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int64
a3'' -> 
  (Status, Int64) -> IO (Status, Int64)
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
a2'', Int64
a3'')

{-# LINE 162 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



-- | Set the stream capture interaction mode for this thread. Return the previous value.
--
-- Requires CUDA-10.1
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1g378135b262f02a43a7caeab239ae493d>
--
-- @since 0.10.1.0
--
mode :: (Mode) -> IO ((Mode))
mode :: Mode -> IO Mode
mode Mode
a1 =
  Mode -> (Ptr CInt -> IO Mode) -> IO Mode
forall a b c.
(Enum a, Integral b, Storable b) =>
a -> (Ptr b -> IO c) -> IO c
withEnum Mode
a1 ((Ptr CInt -> IO Mode) -> IO Mode)
-> (Ptr CInt -> IO Mode) -> IO Mode
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
a1' -> 
  Ptr CInt -> IO CInt
mode'_ Ptr CInt
a1' IO CInt -> (CInt -> IO Mode) -> IO Mode
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  CInt -> IO ()
checkStatus CInt
res IO () -> IO Mode -> IO Mode
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> 
  Ptr CInt -> IO Mode
forall a b. (Enum a, Integral b, Storable b) => Ptr b -> IO a
peekEnum  Ptr CInt
a1'IO Mode -> (Mode -> IO Mode) -> IO Mode
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Mode
a1'' -> 
  Mode -> IO Mode
forall (m :: * -> *) a. Monad m => a -> m a
return (Mode
a1'')

{-# LINE 181 "src/Foreign/CUDA/Driver/Graph/Capture.chs" #-}



--------------------------------------------------------------------------------
-- Internal
--------------------------------------------------------------------------------

{-# INLINE peekGraph #-}
peekGraph :: Ptr ((C2HSImp.Ptr ())) -> IO Graph
peekGraph :: Ptr (Ptr ()) -> IO Graph
peekGraph = (Ptr () -> Graph) -> IO (Ptr ()) -> IO Graph
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Ptr () -> Graph
Graph (IO (Ptr ()) -> IO Graph)
-> (Ptr (Ptr ()) -> IO (Ptr ())) -> Ptr (Ptr ()) -> IO Graph
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr (Ptr ()) -> IO (Ptr ())
forall a. Storable a => Ptr a -> IO a
peek


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

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

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

foreign import ccall unsafe "Foreign/CUDA/Driver/Graph/Capture.chs.h cuStreamGetCaptureInfo"
  info'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr C2HSImp.CInt) -> ((C2HSImp.Ptr C2HSImp.CULLong) -> (IO C2HSImp.CInt))))

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