-- 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/Runtime/Stream.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE ForeignFunctionInterface #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Runtime.Stream
-- Copyright : [2009..2018] Trevor L. McDonell
-- License   : BSD
--
-- Stream management routines
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Runtime.Stream (

  -- * Stream Management
  Stream(..),
  create, destroy, finished, block,

  defaultStream, defaultStreamLegacy, defaultStreamPerThread,

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





{-# LINE 24 "src/Foreign/CUDA/Runtime/Stream.chs" #-}


-- Friends
import Foreign.CUDA.Driver.Stream                         ( Stream(..), defaultStream, defaultStreamLegacy, defaultStreamPerThread )
import Foreign.CUDA.Internal.C2HS
import Foreign.CUDA.Runtime.Error

-- System
import Foreign
import Foreign.C
import Control.Monad                                      ( liftM )
import Control.Exception                                  ( throwIO )


--------------------------------------------------------------------------------
-- Functions
--------------------------------------------------------------------------------

-- |
-- Create a new asynchronous stream
--
{-# INLINEABLE create #-}
create :: IO Stream
create :: IO Stream
create = (Status, Stream) -> IO Stream
forall a. (Status, a) -> IO a
resultIfOk ((Status, Stream) -> IO Stream) -> IO (Status, Stream) -> IO Stream
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Status, Stream)
cudaStreamCreate

{-# INLINE cudaStreamCreate #-}
cudaStreamCreate :: IO ((Status), (Stream))
cudaStreamCreate :: IO (Status, Stream)
cudaStreamCreate =
  (Ptr (Ptr ()) -> IO (Status, Stream)) -> IO (Status, Stream)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr ()) -> IO (Status, Stream)) -> IO (Status, Stream))
-> (Ptr (Ptr ()) -> IO (Status, Stream)) -> IO (Status, Stream)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr ())
a1' -> 
  Ptr (Ptr ()) -> IO CInt
cudaStreamCreate'_ Ptr (Ptr ())
a1' IO CInt -> (CInt -> IO (Status, Stream)) -> IO (Status, Stream)
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 Stream
peekStream  Ptr (Ptr ())
a1'IO Stream -> (Stream -> IO (Status, Stream)) -> IO (Status, Stream)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Stream
a1'' -> 
  (Status, Stream) -> IO (Status, Stream)
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
res', Stream
a1'')

{-# LINE 51 "src/Foreign/CUDA/Runtime/Stream.chs" #-}



-- |
-- Destroy and clean up an asynchronous stream
--
{-# INLINEABLE destroy #-}
destroy :: Stream -> IO ()
destroy :: Stream -> IO ()
destroy !Stream
s = Status -> IO ()
nothingIfOk (Status -> IO ()) -> IO Status -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Stream -> IO Status
cudaStreamDestroy Stream
s

{-# INLINE cudaStreamDestroy #-}
cudaStreamDestroy :: (Stream) -> IO ((Status))
cudaStreamDestroy :: Stream -> IO Status
cudaStreamDestroy Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  Ptr () -> IO CInt
cudaStreamDestroy'_ Ptr ()
a1' IO CInt -> (CInt -> IO Status) -> IO Status
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
  Status -> IO Status
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
res')

{-# LINE 63 "src/Foreign/CUDA/Runtime/Stream.chs" #-}



-- |
-- Determine if all operations in a stream have completed
--
{-# INLINEABLE finished #-}
finished :: Stream -> IO Bool
finished :: Stream -> IO Bool
finished !Stream
s =
  Stream -> IO Status
cudaStreamQuery Stream
s IO Status -> (Status -> IO Bool) -> IO Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Status
rv -> do
  case Status
rv of
      Status
Success  -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
      Status
NotReady -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      Status
_        -> CUDAException -> IO Bool
forall e a. Exception e => e -> IO a
throwIO (Status -> CUDAException
ExitCode Status
rv)

{-# INLINE cudaStreamQuery #-}
cudaStreamQuery :: (Stream) -> IO ((Status))
cudaStreamQuery :: Stream -> IO Status
cudaStreamQuery Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  Ptr () -> IO CInt
cudaStreamQuery'_ Ptr ()
a1' IO CInt -> (CInt -> IO Status) -> IO Status
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
  Status -> IO Status
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
res')

{-# LINE 80 "src/Foreign/CUDA/Runtime/Stream.chs" #-}



-- |
-- Block until all operations in a Stream have been completed
--
{-# INLINEABLE block #-}
block :: Stream -> IO ()
block :: Stream -> IO ()
block !Stream
s = Status -> IO ()
nothingIfOk (Status -> IO ()) -> IO Status -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Stream -> IO Status
cudaStreamSynchronize Stream
s

{-# INLINE cudaStreamSynchronize #-}
cudaStreamSynchronize :: (Stream) -> IO ((Status))
cudaStreamSynchronize :: Stream -> IO Status
cudaStreamSynchronize Stream
a1 =
  let {a1' :: Ptr ()
a1' = Stream -> Ptr ()
useStream Stream
a1} in 
  Ptr () -> IO CInt
cudaStreamSynchronize'_ Ptr ()
a1' IO CInt -> (CInt -> IO Status) -> IO Status
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
  Status -> IO Status
forall (m :: * -> *) a. Monad m => a -> m a
return (Status
res')

{-# LINE 92 "src/Foreign/CUDA/Runtime/Stream.chs" #-}



-- |
-- The main execution stream (0)
--
-- {-# INLINE defaultStream #-}
-- defaultStream :: Stream
-- #if CUDART_VERSION < 3010
-- defaultStream = Stream 0
-- #else
-- defaultStream = Stream nullPtr
-- #endif

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

{-# INLINE peekStream #-}
peekStream :: Ptr ((C2HSImp.Ptr ())) -> IO Stream
peekStream :: Ptr (Ptr ()) -> IO Stream
peekStream = (Ptr () -> Stream) -> IO (Ptr ()) -> IO Stream
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Ptr () -> Stream
Stream (IO (Ptr ()) -> IO Stream)
-> (Ptr (Ptr ()) -> IO (Ptr ())) -> Ptr (Ptr ()) -> IO Stream
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/Runtime/Stream.chs.h cudaStreamCreate"
  cudaStreamCreate'_ :: ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO C2HSImp.CInt))

foreign import ccall unsafe "Foreign/CUDA/Runtime/Stream.chs.h cudaStreamDestroy"
  cudaStreamDestroy'_ :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))

foreign import ccall unsafe "Foreign/CUDA/Runtime/Stream.chs.h cudaStreamQuery"
  cudaStreamQuery'_ :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))

foreign import ccall safe "Foreign/CUDA/Runtime/Stream.chs.h cudaStreamSynchronize"
  cudaStreamSynchronize'_ :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))