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

module Foreign.CUDA.Driver.Error (

  -- * CUDA Errors
  Status(..), CUDAException(..),
  describe,
  cudaError, cudaErrorIO, requireSDK,
  resultIfOk, nothingIfOk, checkStatus,

) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified System.IO.Unsafe as C2HSImp



-- Friends
import Foreign.CUDA.Internal.C2HS
import Text.Show.Describe

-- System
import Control.Exception
import Control.Monad
import Data.Typeable
import Foreign.C
import Foreign.Marshal
import Foreign.Ptr
import Foreign.Storable
import Language.Haskell.TH
import System.IO.Unsafe
import Text.Printf




{-# LINE 42 "src/Foreign/CUDA/Driver/Error.chs" #-}



--------------------------------------------------------------------------------
-- Return Status
--------------------------------------------------------------------------------

--
-- Error Codes
--
data Status = Success
            | InvalidValue
            | OutOfMemory
            | NotInitialized
            | Deinitialized
            | ProfilerDisabled
            | ProfilerNotInitialized
            | ProfilerAlreadyStarted
            | ProfilerAlreadyStopped
            | NoDevice
            | InvalidDevice
            | InvalidImage
            | InvalidContext
            | ContextAlreadyCurrent
            | MapFailed
            | UnmapFailed
            | ArrayIsMapped
            | AlreadyMapped
            | NoBinaryForGPU
            | AlreadyAcquired
            | NotMapped
            | NotMappedAsArray
            | NotMappedAsPointer
            | EccUncorrectable
            | UnsupportedLimit
            | ContextAlreadyInUse
            | PeerAccessUnsupported
            | InvalidPTX
            | InvalidGraphicsContext
            | NvlinkUncorrectable
            | JitCompilerNotFound
            | InvalidSource
            | FileNotFound
            | SharedObjectSymbolNotFound
            | SharedObjectInitFailed
            | OperatingSystem
            | InvalidHandle
            | IllegalState
            | NotFound
            | NotReady
            | IllegalAddress
            | LaunchOutOfResources
            | LaunchTimeout
            | LaunchIncompatibleTexturing
            | PeerAccessAlreadyEnabled
            | PeerAccessNotEnabled
            | PrimaryContextActive
            | ContextIsDestroyed
            | Assert
            | TooManyPeers
            | HostMemoryAlreadyRegistered
            | HostMemoryNotRegistered
            | HardwareStackError
            | IllegalInstruction
            | MisalignedAddress
            | InvalidAddressSpace
            | InvalidPC
            | LaunchFailed
            | CooperativeLaunchTooLarge
            | NotPermitted
            | NotSupported
            | SystemNotReady
            | SystemDriverMismatch
            | CompatNotSupportedOnDevice
            | StreamCaptureUnsupported
            | StreamCaptureInvalidated
            | StreamCaptureMerge
            | StreamCaptureUnmatched
            | StreamCaptureUnjoined
            | StreamCaptureIsolation
            | StreamCaptureImplicit
            | CapturedEvent
            | StreamCaptureWrongThread
            | Timeout
            | GraphExecUpdateFailure
            | Unknown
  deriving (Eq,Show)
instance Enum Status where
  succ Success = InvalidValue
  succ InvalidValue = OutOfMemory
  succ OutOfMemory = NotInitialized
  succ NotInitialized = Deinitialized
  succ Deinitialized = ProfilerDisabled
  succ ProfilerDisabled = ProfilerNotInitialized
  succ ProfilerNotInitialized = ProfilerAlreadyStarted
  succ ProfilerAlreadyStarted = ProfilerAlreadyStopped
  succ ProfilerAlreadyStopped = NoDevice
  succ NoDevice = InvalidDevice
  succ InvalidDevice = InvalidImage
  succ InvalidImage = InvalidContext
  succ InvalidContext = ContextAlreadyCurrent
  succ ContextAlreadyCurrent = MapFailed
  succ MapFailed = UnmapFailed
  succ UnmapFailed = ArrayIsMapped
  succ ArrayIsMapped = AlreadyMapped
  succ AlreadyMapped = NoBinaryForGPU
  succ NoBinaryForGPU = AlreadyAcquired
  succ AlreadyAcquired = NotMapped
  succ NotMapped = NotMappedAsArray
  succ NotMappedAsArray = NotMappedAsPointer
  succ NotMappedAsPointer = EccUncorrectable
  succ EccUncorrectable = UnsupportedLimit
  succ UnsupportedLimit = ContextAlreadyInUse
  succ ContextAlreadyInUse = PeerAccessUnsupported
  succ PeerAccessUnsupported = InvalidPTX
  succ InvalidPTX = InvalidGraphicsContext
  succ InvalidGraphicsContext = NvlinkUncorrectable
  succ NvlinkUncorrectable = JitCompilerNotFound
  succ JitCompilerNotFound = InvalidSource
  succ InvalidSource = FileNotFound
  succ FileNotFound = SharedObjectSymbolNotFound
  succ SharedObjectSymbolNotFound = SharedObjectInitFailed
  succ SharedObjectInitFailed = OperatingSystem
  succ OperatingSystem = InvalidHandle
  succ InvalidHandle = IllegalState
  succ IllegalState = NotFound
  succ NotFound = NotReady
  succ NotReady = IllegalAddress
  succ IllegalAddress = LaunchOutOfResources
  succ LaunchOutOfResources = LaunchTimeout
  succ LaunchTimeout = LaunchIncompatibleTexturing
  succ LaunchIncompatibleTexturing = PeerAccessAlreadyEnabled
  succ PeerAccessAlreadyEnabled = PeerAccessNotEnabled
  succ PeerAccessNotEnabled = PrimaryContextActive
  succ PrimaryContextActive = ContextIsDestroyed
  succ ContextIsDestroyed = Assert
  succ Assert = TooManyPeers
  succ TooManyPeers = HostMemoryAlreadyRegistered
  succ HostMemoryAlreadyRegistered = HostMemoryNotRegistered
  succ HostMemoryNotRegistered = HardwareStackError
  succ HardwareStackError = IllegalInstruction
  succ IllegalInstruction = MisalignedAddress
  succ MisalignedAddress = InvalidAddressSpace
  succ InvalidAddressSpace = InvalidPC
  succ InvalidPC = LaunchFailed
  succ LaunchFailed = CooperativeLaunchTooLarge
  succ CooperativeLaunchTooLarge = NotPermitted
  succ NotPermitted = NotSupported
  succ NotSupported = SystemNotReady
  succ SystemNotReady = SystemDriverMismatch
  succ SystemDriverMismatch = CompatNotSupportedOnDevice
  succ CompatNotSupportedOnDevice = StreamCaptureUnsupported
  succ StreamCaptureUnsupported = StreamCaptureInvalidated
  succ StreamCaptureInvalidated = StreamCaptureMerge
  succ StreamCaptureMerge = StreamCaptureUnmatched
  succ StreamCaptureUnmatched = StreamCaptureUnjoined
  succ StreamCaptureUnjoined = StreamCaptureIsolation
  succ StreamCaptureIsolation = StreamCaptureImplicit
  succ StreamCaptureImplicit = CapturedEvent
  succ CapturedEvent = StreamCaptureWrongThread
  succ StreamCaptureWrongThread = Timeout
  succ Timeout = GraphExecUpdateFailure
  succ GraphExecUpdateFailure = Unknown
  succ Unknown = error "Status.succ: Unknown has no successor"

  pred :: Status -> Status
pred Status
InvalidValue = Status
Success
  pred Status
OutOfMemory = Status
InvalidValue
  pred Status
NotInitialized = Status
OutOfMemory
  pred Status
Deinitialized = Status
NotInitialized
  pred Status
ProfilerDisabled = Status
Deinitialized
  pred Status
ProfilerNotInitialized = Status
ProfilerDisabled
  pred Status
ProfilerAlreadyStarted = Status
ProfilerNotInitialized
  pred Status
ProfilerAlreadyStopped = Status
ProfilerAlreadyStarted
  pred Status
NoDevice = Status
ProfilerAlreadyStopped
  pred Status
InvalidDevice = Status
NoDevice
  pred Status
InvalidImage = Status
InvalidDevice
  pred Status
InvalidContext = Status
InvalidImage
  pred Status
ContextAlreadyCurrent = Status
InvalidContext
  pred Status
MapFailed = Status
ContextAlreadyCurrent
  pred Status
UnmapFailed = Status
MapFailed
  pred Status
ArrayIsMapped = Status
UnmapFailed
  pred Status
AlreadyMapped = Status
ArrayIsMapped
  pred Status
NoBinaryForGPU = Status
AlreadyMapped
  pred Status
AlreadyAcquired = Status
NoBinaryForGPU
  pred Status
NotMapped = Status
AlreadyAcquired
  pred Status
NotMappedAsArray = Status
NotMapped
  pred Status
NotMappedAsPointer = Status
NotMappedAsArray
  pred Status
EccUncorrectable = Status
NotMappedAsPointer
  pred Status
UnsupportedLimit = Status
EccUncorrectable
  pred Status
ContextAlreadyInUse = Status
UnsupportedLimit
  pred Status
PeerAccessUnsupported = Status
ContextAlreadyInUse
  pred Status
InvalidPTX = Status
PeerAccessUnsupported
  pred Status
InvalidGraphicsContext = Status
InvalidPTX
  pred Status
NvlinkUncorrectable = Status
InvalidGraphicsContext
  pred Status
JitCompilerNotFound = Status
NvlinkUncorrectable
  pred Status
InvalidSource = Status
JitCompilerNotFound
  pred Status
FileNotFound = Status
InvalidSource
  pred Status
SharedObjectSymbolNotFound = Status
FileNotFound
  pred Status
SharedObjectInitFailed = Status
SharedObjectSymbolNotFound
  pred Status
OperatingSystem = Status
SharedObjectInitFailed
  pred Status
InvalidHandle = Status
OperatingSystem
  pred Status
IllegalState = Status
InvalidHandle
  pred Status
NotFound = Status
IllegalState
  pred Status
NotReady = Status
NotFound
  pred Status
IllegalAddress = Status
NotReady
  pred Status
LaunchOutOfResources = Status
IllegalAddress
  pred Status
LaunchTimeout = Status
LaunchOutOfResources
  pred Status
LaunchIncompatibleTexturing = Status
LaunchTimeout
  pred Status
PeerAccessAlreadyEnabled = Status
LaunchIncompatibleTexturing
  pred Status
PeerAccessNotEnabled = Status
PeerAccessAlreadyEnabled
  pred Status
PrimaryContextActive = Status
PeerAccessNotEnabled
  pred Status
ContextIsDestroyed = Status
PrimaryContextActive
  pred Status
Assert = Status
ContextIsDestroyed
  pred Status
TooManyPeers = Status
Assert
  pred Status
HostMemoryAlreadyRegistered = Status
TooManyPeers
  pred Status
HostMemoryNotRegistered = Status
HostMemoryAlreadyRegistered
  pred Status
HardwareStackError = Status
HostMemoryNotRegistered
  pred Status
IllegalInstruction = Status
HardwareStackError
  pred Status
MisalignedAddress = Status
IllegalInstruction
  pred Status
InvalidAddressSpace = Status
MisalignedAddress
  pred Status
InvalidPC = Status
InvalidAddressSpace
  pred Status
LaunchFailed = Status
InvalidPC
  pred Status
CooperativeLaunchTooLarge = Status
LaunchFailed
  pred Status
NotPermitted = Status
CooperativeLaunchTooLarge
  pred Status
NotSupported = Status
NotPermitted
  pred Status
SystemNotReady = Status
NotSupported
  pred Status
SystemDriverMismatch = Status
SystemNotReady
  pred Status
CompatNotSupportedOnDevice = Status
SystemDriverMismatch
  pred Status
StreamCaptureUnsupported = Status
CompatNotSupportedOnDevice
  pred Status
StreamCaptureInvalidated = Status
StreamCaptureUnsupported
  pred Status
StreamCaptureMerge = Status
StreamCaptureInvalidated
  pred Status
StreamCaptureUnmatched = Status
StreamCaptureMerge
  pred Status
StreamCaptureUnjoined = Status
StreamCaptureUnmatched
  pred Status
StreamCaptureIsolation = Status
StreamCaptureUnjoined
  pred Status
StreamCaptureImplicit = Status
StreamCaptureIsolation
  pred Status
CapturedEvent = Status
StreamCaptureImplicit
  pred Status
StreamCaptureWrongThread = Status
CapturedEvent
  pred Status
Timeout = Status
StreamCaptureWrongThread
  pred Status
GraphExecUpdateFailure = Status
Timeout
  pred Status
Unknown = Status
GraphExecUpdateFailure
  pred Status
Success = String -> Status
forall a. HasCallStack => String -> a
error String
"Status.pred: Success 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 :: Int
end = Status -> Int
forall a. Enum a => a -> Int
fromEnum Status
to
      go :: t -> [t]
go t
v = case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (t -> Int
forall a. Enum a => a -> Int
fromEnum t
v) Int
end of
                 Ordering
LT -> t
v t -> [t] -> [t]
forall a. a -> [a] -> [a]
: t -> [t]
go (t -> t
forall a. Enum a => a -> a
succ t
v)
                 Ordering
EQ -> [t
v]
                 Ordering
GT -> []

  enumFrom :: Status -> [Status]
enumFrom Status
from = Status -> Status -> [Status]
forall a. Enum a => a -> a -> [a]
enumFromTo Status
from Status
Unknown

  fromEnum :: Status -> Int
fromEnum Status
Success = Int
0
  fromEnum Status
InvalidValue = Int
1
  fromEnum Status
OutOfMemory = Int
2
  fromEnum Status
NotInitialized = Int
3
  fromEnum Status
Deinitialized = Int
4
  fromEnum Status
ProfilerDisabled = Int
5
  fromEnum Status
ProfilerNotInitialized = Int
6
  fromEnum Status
ProfilerAlreadyStarted = Int
7
  fromEnum Status
ProfilerAlreadyStopped = Int
8
  fromEnum Status
NoDevice = Int
100
  fromEnum Status
InvalidDevice = Int
101
  fromEnum Status
InvalidImage = Int
200
  fromEnum Status
InvalidContext = Int
201
  fromEnum Status
ContextAlreadyCurrent = Int
202
  fromEnum Status
MapFailed = Int
205
  fromEnum Status
UnmapFailed = Int
206
  fromEnum Status
ArrayIsMapped = Int
207
  fromEnum Status
AlreadyMapped = Int
208
  fromEnum Status
NoBinaryForGPU = Int
209
  fromEnum Status
AlreadyAcquired = Int
210
  fromEnum Status
NotMapped = Int
211
  fromEnum Status
NotMappedAsArray = Int
212
  fromEnum Status
NotMappedAsPointer = Int
213
  fromEnum Status
EccUncorrectable = Int
214
  fromEnum Status
UnsupportedLimit = Int
215
  fromEnum Status
ContextAlreadyInUse = Int
216
  fromEnum Status
PeerAccessUnsupported = Int
217
  fromEnum Status
InvalidPTX = Int
218
  fromEnum Status
InvalidGraphicsContext = Int
219
  fromEnum Status
NvlinkUncorrectable = Int
220
  fromEnum Status
JitCompilerNotFound = Int
221
  fromEnum Status
InvalidSource = Int
300
  fromEnum Status
FileNotFound = Int
301
  fromEnum Status
SharedObjectSymbolNotFound = Int
302
  fromEnum Status
SharedObjectInitFailed = Int
303
  fromEnum Status
OperatingSystem = Int
304
  fromEnum Status
InvalidHandle = Int
400
  fromEnum Status
IllegalState = Int
401
  fromEnum Status
NotFound = Int
500
  fromEnum Status
NotReady = Int
600
  fromEnum Status
IllegalAddress = Int
700
  fromEnum Status
LaunchOutOfResources = Int
701
  fromEnum Status
LaunchTimeout = Int
702
  fromEnum Status
LaunchIncompatibleTexturing = Int
703
  fromEnum Status
PeerAccessAlreadyEnabled = Int
704
  fromEnum Status
PeerAccessNotEnabled = Int
705
  fromEnum Status
PrimaryContextActive = Int
708
  fromEnum Status
ContextIsDestroyed = Int
709
  fromEnum Status
Assert = Int
710
  fromEnum Status
TooManyPeers = Int
711
  fromEnum Status
HostMemoryAlreadyRegistered = Int
712
  fromEnum Status
HostMemoryNotRegistered = Int
713
  fromEnum Status
HardwareStackError = Int
714
  fromEnum Status
IllegalInstruction = Int
715
  fromEnum Status
MisalignedAddress = Int
716
  fromEnum Status
InvalidAddressSpace = Int
717
  fromEnum Status
InvalidPC = Int
718
  fromEnum Status
LaunchFailed = Int
719
  fromEnum Status
CooperativeLaunchTooLarge = Int
720
  fromEnum Status
NotPermitted = Int
800
  fromEnum Status
NotSupported = Int
801
  fromEnum Status
SystemNotReady = Int
802
  fromEnum Status
SystemDriverMismatch = Int
803
  fromEnum Status
CompatNotSupportedOnDevice = Int
804
  fromEnum Status
StreamCaptureUnsupported = Int
900
  fromEnum Status
StreamCaptureInvalidated = Int
901
  fromEnum Status
StreamCaptureMerge = Int
902
  fromEnum Status
StreamCaptureUnmatched = Int
903
  fromEnum Status
StreamCaptureUnjoined = Int
904
  fromEnum Status
StreamCaptureIsolation = Int
905
  fromEnum Status
StreamCaptureImplicit = Int
906
  fromEnum Status
CapturedEvent = Int
907
  fromEnum Status
StreamCaptureWrongThread = Int
908
  fromEnum Status
Timeout = Int
909
  fromEnum Status
GraphExecUpdateFailure = Int
910
  fromEnum Status
Unknown = Int
999

  toEnum :: Int -> Status
toEnum Int
0 = Status
Success
  toEnum Int
1 = Status
InvalidValue
  toEnum Int
2 = Status
OutOfMemory
  toEnum Int
3 = Status
NotInitialized
  toEnum Int
4 = Status
Deinitialized
  toEnum Int
5 = Status
ProfilerDisabled
  toEnum Int
6 = Status
ProfilerNotInitialized
  toEnum Int
7 = Status
ProfilerAlreadyStarted
  toEnum Int
8 = Status
ProfilerAlreadyStopped
  toEnum Int
100 = Status
NoDevice
  toEnum Int
101 = Status
InvalidDevice
  toEnum Int
200 = Status
InvalidImage
  toEnum Int
201 = Status
InvalidContext
  toEnum Int
202 = Status
ContextAlreadyCurrent
  toEnum Int
205 = Status
MapFailed
  toEnum Int
206 = Status
UnmapFailed
  toEnum Int
207 = Status
ArrayIsMapped
  toEnum Int
208 = Status
AlreadyMapped
  toEnum Int
209 = Status
NoBinaryForGPU
  toEnum Int
210 = Status
AlreadyAcquired
  toEnum Int
211 = Status
NotMapped
  toEnum Int
212 = Status
NotMappedAsArray
  toEnum Int
213 = Status
NotMappedAsPointer
  toEnum Int
214 = Status
EccUncorrectable
  toEnum Int
215 = Status
UnsupportedLimit
  toEnum Int
216 = Status
ContextAlreadyInUse
  toEnum Int
217 = Status
PeerAccessUnsupported
  toEnum Int
218 = Status
InvalidPTX
  toEnum Int
219 = Status
InvalidGraphicsContext
  toEnum Int
220 = Status
NvlinkUncorrectable
  toEnum Int
221 = Status
JitCompilerNotFound
  toEnum Int
300 = Status
InvalidSource
  toEnum Int
301 = Status
FileNotFound
  toEnum Int
302 = Status
SharedObjectSymbolNotFound
  toEnum Int
303 = Status
SharedObjectInitFailed
  toEnum Int
304 = Status
OperatingSystem
  toEnum Int
400 = Status
InvalidHandle
  toEnum Int
401 = Status
IllegalState
  toEnum Int
500 = Status
NotFound
  toEnum Int
600 = Status
NotReady
  toEnum Int
700 = Status
IllegalAddress
  toEnum Int
701 = Status
LaunchOutOfResources
  toEnum Int
702 = Status
LaunchTimeout
  toEnum Int
703 = Status
LaunchIncompatibleTexturing
  toEnum Int
704 = Status
PeerAccessAlreadyEnabled
  toEnum Int
705 = Status
PeerAccessNotEnabled
  toEnum Int
708 = Status
PrimaryContextActive
  toEnum Int
709 = Status
ContextIsDestroyed
  toEnum Int
710 = Status
Assert
  toEnum Int
711 = Status
TooManyPeers
  toEnum Int
712 = Status
HostMemoryAlreadyRegistered
  toEnum Int
713 = Status
HostMemoryNotRegistered
  toEnum Int
714 = Status
HardwareStackError
  toEnum Int
715 = Status
IllegalInstruction
  toEnum Int
716 = Status
MisalignedAddress
  toEnum Int
717 = Status
InvalidAddressSpace
  toEnum Int
718 = Status
InvalidPC
  toEnum Int
719 = Status
LaunchFailed
  toEnum Int
720 = Status
CooperativeLaunchTooLarge
  toEnum Int
800 = Status
NotPermitted
  toEnum Int
801 = Status
NotSupported
  toEnum Int
802 = Status
SystemNotReady
  toEnum Int
803 = Status
SystemDriverMismatch
  toEnum Int
804 = Status
CompatNotSupportedOnDevice
  toEnum Int
900 = Status
StreamCaptureUnsupported
  toEnum Int
901 = Status
StreamCaptureInvalidated
  toEnum Int
902 = Status
StreamCaptureMerge
  toEnum Int
903 = Status
StreamCaptureUnmatched
  toEnum Int
904 = Status
StreamCaptureUnjoined
  toEnum Int
905 = Status
StreamCaptureIsolation
  toEnum Int
906 = Status
StreamCaptureImplicit
  toEnum Int
907 = Status
CapturedEvent
  toEnum Int
908 = Status
StreamCaptureWrongThread
  toEnum Int
909 = Status
Timeout
  toEnum Int
910 = Status
GraphExecUpdateFailure
  toEnum Int
999 = Status
Unknown
  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 59 "src/Foreign/CUDA/Driver/Error.chs" #-}



-- |
-- Return a descriptive error string associated with a particular error code
--
instance Describe Status where
  describe status =
    case cuGetErrorString status of
      (Success, msg) -> msg
      (err, _)       -> throw (ExitCode err)

cuGetErrorString :: (Status) -> ((Status), (String))
cuGetErrorString a1 =
  C2HSImp.unsafePerformIO $
  let {a1' = cFromEnum a1} in 
  alloca $ \a2' -> 
  cuGetErrorString'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  ppeek  a2'>>= \a2'' -> 
  return (res', a2'')

{-# LINE 74 "src/Foreign/CUDA/Driver/Error.chs" #-}

    where
      ppeek = peek >=> peekCString


--------------------------------------------------------------------------------
-- Exceptions
--------------------------------------------------------------------------------

data CUDAException
  = ExitCode Status
  | UserError String
  deriving Typeable

instance Exception CUDAException

instance Show CUDAException where
  showsPrec _ (ExitCode  s) = showString ("CUDA Exception: " ++ describe s)
  showsPrec _ (UserError s) = showString ("CUDA Exception: " ++ s)


-- |
-- Raise a CUDAException. Exceptions can be thrown from pure code, but can only
-- be caught in the 'IO' monad.
--
{-# RULES "cudaError/IO" cudaError = cudaErrorIO #-}
{-# NOINLINE [1] cudaError #-}
cudaError :: String -> a
cudaError s = throw (UserError s)

-- |
-- Raise a CUDAException in the IO Monad
--
cudaErrorIO :: String -> IO a
cudaErrorIO s = throwIO (UserError s)

-- |
-- A specially formatted error message
--
requireSDK :: Name -> Double -> a
requireSDK n v = cudaError $ printf "'%s' requires at least cuda-%3.1f\n" (show n) v


--------------------------------------------------------------------------------
-- Helper Functions
--------------------------------------------------------------------------------


-- |
-- Return the results of a function on successful execution, otherwise throw an
-- exception with an error string associated with the return code
--
{-# INLINE resultIfOk #-}
resultIfOk :: (Status, a) -> IO a
resultIfOk (status, !result) =
    case status of
        Success -> return  result
        _       -> throwIO (ExitCode status)


-- |
-- Throw an exception with an error string associated with an unsuccessful
-- return code, otherwise return unit.
--
{-# INLINE nothingIfOk #-}
nothingIfOk :: Status -> IO ()
nothingIfOk status =
    case status of
        Success -> return  ()
        _       -> throwIO (ExitCode status)

{-# INLINE checkStatus #-}
checkStatus :: CInt -> IO ()
checkStatus = nothingIfOk . cToEnum


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