{-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE TemplateHaskell #-} #ifdef USE_EMPTY_CASE {-# LANGUAGE EmptyCase #-} #endif -------------------------------------------------------------------------------- -- | -- 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 #include "cbits/stubs.h" {# context lib="cuda" #} 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 #if CUDA_VERSION < 10000 data Status instance Enum Status where #ifdef USE_EMPTY_CASE toEnum x = error ("Status.toEnum: Cannot match " ++ show x) fromEnum x = case x of {} #endif #else {# enum CUstreamCaptureStatus as Status { underscoreToCase } with prefix="CU_STREAM_CAPTURE_STATUS" deriving (Eq, Show, Bounded) #} #endif #if CUDA_VERSION < 10010 data Mode instance Enum Mode where #ifdef USE_EMPTY_CASE toEnum x = error ("Mode.toEnum: Cannot match " ++ show x) fromEnum x = case x of {} #endif #else {# enum CUstreamCaptureMode as Mode { underscoreToCase } with prefix="CU_STREAM_CAPTURE_MODE" deriving (Eq, Show, Bounded) #} #endif -------------------------------------------------------------------------------- -- Graph capture -------------------------------------------------------------------------------- -- | Begin graph capture on a stream -- -- Requires CUDA-10.0 -- -- -- -- @since 0.10.0.0 -- #if CUDA_VERSION < 10000 start :: Stream -> Mode -> IO () start = requireSDK 'start 10.0 #elif CUDA_VERSION < 10010 start :: Stream -> Mode -> IO () start s _ = cuStreamBeginCapture s where {# fun unsafe cuStreamBeginCapture { useStream `Stream' } -> `()' checkStatus*- #} #else {# fun unsafe cuStreamBeginCapture as start { useStream `Stream' , `Mode' } -> `()' checkStatus*- #} #endif -- | End graph capture on a stream -- -- Requires CUDA-10.0 -- -- -- -- @since 0.10.0.0 -- #if CUDA_VERSION < 10000 stop :: Stream -> IO Graph stop = requireSDK 'stop 10.0 #else {# fun unsafe cuStreamEndCapture as stop { useStream `Stream' , alloca- `Graph' peekGraph* } -> `()' checkStatus*- #} #endif -- | Return a stream's capture status -- -- Requires CUDA-10.0 -- -- -- -- @since 0.10.0.0 -- #if CUDA_VERSION < 10000 status :: Stream -> IO Status status = requireSDK 'status 10.0 #else {# fun unsafe cuStreamIsCapturing as status { useStream `Stream' , alloca- `Status' peekEnum* } -> `()' checkStatus*- #} #endif -- | 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 -- -- -- -- @since 0.10.1.0 -- #if CUDA_VERSION < 10010 info :: Stream -> IO (Status, Int64) info = requireSDK 'info 10.1 #else {# fun unsafe cuStreamGetCaptureInfo as info { useStream `Stream' , alloca- `Status' peekEnum* , alloca- `Int64' peekIntConv* } -> `()' checkStatus*- #} #endif -- | Set the stream capture interaction mode for this thread. Return the previous value. -- -- Requires CUDA-10.1 -- -- -- -- @since 0.10.1.0 -- #if CUDA_VERSION < 10010 mode :: Mode -> IO Mode mode = requireSDK 'mode 10.1 #else {# fun unsafe cuThreadExchangeStreamCaptureMode as mode { withEnum* `Mode' peekEnum* } -> `()' checkStatus*- #} #endif -------------------------------------------------------------------------------- -- Internal -------------------------------------------------------------------------------- #if CUDA_VERSION >= 10000 {-# INLINE peekGraph #-} peekGraph :: Ptr {# type CUgraph #} -> IO Graph peekGraph = liftM Graph . peek #endif