-- GENERATED by C->Haskell Compiler, version 0.28.2 Switcheroo, 1 April 2016 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/Foreign/CUDA/Runtime/Error.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE DeriveDataTypeable       #-}
{-# LANGUAGE ForeignFunctionInterface #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Runtime.Error
-- Copyright : [2009..2017] Trevor L. McDonell
-- License   : BSD
--
-- Error handling functions
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Runtime.Error (

  Status(..), CUDAException(..),

  cudaError, describe, requireSDK,
  resultIfOk, nothingIfOk

) where
import qualified Foreign.C.String as C2HSImp
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 Data.Typeable
import Foreign.C
import Foreign.Ptr
import Language.Haskell.TH
import System.IO.Unsafe
import Text.Printf



{-# LINE 37 "src/Foreign/CUDA/Runtime/Error.chs" #-}



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

-- |
-- Return codes from API functions
--
data Status = Success
            | MissingConfiguration
            | MemoryAllocation
            | InitializationError
            | LaunchFailure
            | PriorLaunchFailure
            | LaunchTimeout
            | LaunchOutOfResources
            | InvalidDeviceFunction
            | InvalidConfiguration
            | InvalidDevice
            | InvalidValue
            | InvalidPitchValue
            | InvalidSymbol
            | MapBufferObjectFailed
            | UnmapBufferObjectFailed
            | InvalidHostPointer
            | InvalidDevicePointer
            | InvalidTexture
            | InvalidTextureBinding
            | InvalidChannelDescriptor
            | InvalidMemcpyDirection
            | AddressOfConstant
            | TextureFetchFailed
            | TextureNotBound
            | SynchronizationError
            | InvalidFilterSetting
            | InvalidNormSetting
            | MixedDeviceExecution
            | CudartUnloading
            | Unknown
            | NotYetImplemented
            | MemoryValueTooLarge
            | InvalidResourceHandle
            | NotReady
            | InsufficientDriver
            | SetOnActiveProcess
            | InvalidSurface
            | NoDevice
            | ECCUncorrectable
            | SharedObjectSymbolNotFound
            | SharedObjectInitFailed
            | UnsupportedLimit
            | DuplicateVariableName
            | DuplicateTextureName
            | DuplicateSurfaceName
            | DevicesUnavailable
            | InvalidKernelImage
            | NoKernelImageForDevice
            | IncompatibleDriverContext
            | PeerAccessAlreadyEnabled
            | PeerAccessNotEnabled
            | DeviceAlreadyInUse
            | ProfilerDisabled
            | ProfilerNotInitialized
            | ProfilerAlreadyStarted
            | ProfilerAlreadyStopped
            | Assert
            | TooManyPeers
            | HostMemoryAlreadyRegistered
            | HostMemoryNotRegistered
            | OperatingSystem
            | PeerAccessUnsupported
            | LaunchMaxDepthExceeded
            | LaunchFileScopedTex
            | LaunchFileScopedSurf
            | SyncDepthExceeded
            | LaunchPendingCountExceeded
            | NotPermitted
            | NotSupported
            | HardwareStackError
            | IllegalInstruction
            | MisalignedAddress
            | InvalidAddressSpace
            | InvalidPc
            | IllegalAddress
            | InvalidPtx
            | InvalidGraphicsContext
            | NvlinkUncorrectable
            | StartupFailure
            | ApiFailureBase
  deriving (Eq,Show)
instance Enum Status where
  succ Success = MissingConfiguration
  succ MissingConfiguration = MemoryAllocation
  succ MemoryAllocation = InitializationError
  succ InitializationError = LaunchFailure
  succ LaunchFailure = PriorLaunchFailure
  succ PriorLaunchFailure = LaunchTimeout
  succ LaunchTimeout = LaunchOutOfResources
  succ LaunchOutOfResources = InvalidDeviceFunction
  succ InvalidDeviceFunction = InvalidConfiguration
  succ InvalidConfiguration = InvalidDevice
  succ InvalidDevice = InvalidValue
  succ InvalidValue = InvalidPitchValue
  succ InvalidPitchValue = InvalidSymbol
  succ InvalidSymbol = MapBufferObjectFailed
  succ MapBufferObjectFailed = UnmapBufferObjectFailed
  succ UnmapBufferObjectFailed = InvalidHostPointer
  succ InvalidHostPointer = InvalidDevicePointer
  succ InvalidDevicePointer = InvalidTexture
  succ InvalidTexture = InvalidTextureBinding
  succ InvalidTextureBinding = InvalidChannelDescriptor
  succ InvalidChannelDescriptor = InvalidMemcpyDirection
  succ InvalidMemcpyDirection = AddressOfConstant
  succ AddressOfConstant = TextureFetchFailed
  succ TextureFetchFailed = TextureNotBound
  succ TextureNotBound = SynchronizationError
  succ SynchronizationError = InvalidFilterSetting
  succ InvalidFilterSetting = InvalidNormSetting
  succ InvalidNormSetting = MixedDeviceExecution
  succ MixedDeviceExecution = CudartUnloading
  succ CudartUnloading = Unknown
  succ Unknown = NotYetImplemented
  succ NotYetImplemented = MemoryValueTooLarge
  succ MemoryValueTooLarge = InvalidResourceHandle
  succ InvalidResourceHandle = NotReady
  succ NotReady = InsufficientDriver
  succ InsufficientDriver = SetOnActiveProcess
  succ SetOnActiveProcess = InvalidSurface
  succ InvalidSurface = NoDevice
  succ NoDevice = ECCUncorrectable
  succ ECCUncorrectable = SharedObjectSymbolNotFound
  succ SharedObjectSymbolNotFound = SharedObjectInitFailed
  succ SharedObjectInitFailed = UnsupportedLimit
  succ UnsupportedLimit = DuplicateVariableName
  succ DuplicateVariableName = DuplicateTextureName
  succ DuplicateTextureName = DuplicateSurfaceName
  succ DuplicateSurfaceName = DevicesUnavailable
  succ DevicesUnavailable = InvalidKernelImage
  succ InvalidKernelImage = NoKernelImageForDevice
  succ NoKernelImageForDevice = IncompatibleDriverContext
  succ IncompatibleDriverContext = PeerAccessAlreadyEnabled
  succ PeerAccessAlreadyEnabled = PeerAccessNotEnabled
  succ PeerAccessNotEnabled = DeviceAlreadyInUse
  succ DeviceAlreadyInUse = ProfilerDisabled
  succ ProfilerDisabled = ProfilerNotInitialized
  succ ProfilerNotInitialized = ProfilerAlreadyStarted
  succ ProfilerAlreadyStarted = ProfilerAlreadyStopped
  succ ProfilerAlreadyStopped = Assert
  succ Assert = TooManyPeers
  succ TooManyPeers = HostMemoryAlreadyRegistered
  succ HostMemoryAlreadyRegistered = HostMemoryNotRegistered
  succ HostMemoryNotRegistered = OperatingSystem
  succ OperatingSystem = PeerAccessUnsupported
  succ PeerAccessUnsupported = LaunchMaxDepthExceeded
  succ LaunchMaxDepthExceeded = LaunchFileScopedTex
  succ LaunchFileScopedTex = LaunchFileScopedSurf
  succ LaunchFileScopedSurf = SyncDepthExceeded
  succ SyncDepthExceeded = LaunchPendingCountExceeded
  succ LaunchPendingCountExceeded = NotPermitted
  succ NotPermitted = NotSupported
  succ NotSupported = HardwareStackError
  succ HardwareStackError = IllegalInstruction
  succ IllegalInstruction = MisalignedAddress
  succ MisalignedAddress = InvalidAddressSpace
  succ InvalidAddressSpace = InvalidPc
  succ InvalidPc = IllegalAddress
  succ IllegalAddress = InvalidPtx
  succ InvalidPtx = InvalidGraphicsContext
  succ InvalidGraphicsContext = NvlinkUncorrectable
  succ NvlinkUncorrectable = StartupFailure
  succ StartupFailure = ApiFailureBase
  succ ApiFailureBase = error "Status.succ: ApiFailureBase has no successor"

  pred MissingConfiguration = Success
  pred MemoryAllocation = MissingConfiguration
  pred InitializationError = MemoryAllocation
  pred LaunchFailure = InitializationError
  pred PriorLaunchFailure = LaunchFailure
  pred LaunchTimeout = PriorLaunchFailure
  pred LaunchOutOfResources = LaunchTimeout
  pred InvalidDeviceFunction = LaunchOutOfResources
  pred InvalidConfiguration = InvalidDeviceFunction
  pred InvalidDevice = InvalidConfiguration
  pred InvalidValue = InvalidDevice
  pred InvalidPitchValue = InvalidValue
  pred InvalidSymbol = InvalidPitchValue
  pred MapBufferObjectFailed = InvalidSymbol
  pred UnmapBufferObjectFailed = MapBufferObjectFailed
  pred InvalidHostPointer = UnmapBufferObjectFailed
  pred InvalidDevicePointer = InvalidHostPointer
  pred InvalidTexture = InvalidDevicePointer
  pred InvalidTextureBinding = InvalidTexture
  pred InvalidChannelDescriptor = InvalidTextureBinding
  pred InvalidMemcpyDirection = InvalidChannelDescriptor
  pred AddressOfConstant = InvalidMemcpyDirection
  pred TextureFetchFailed = AddressOfConstant
  pred TextureNotBound = TextureFetchFailed
  pred SynchronizationError = TextureNotBound
  pred InvalidFilterSetting = SynchronizationError
  pred InvalidNormSetting = InvalidFilterSetting
  pred MixedDeviceExecution = InvalidNormSetting
  pred CudartUnloading = MixedDeviceExecution
  pred Unknown = CudartUnloading
  pred NotYetImplemented = Unknown
  pred MemoryValueTooLarge = NotYetImplemented
  pred InvalidResourceHandle = MemoryValueTooLarge
  pred NotReady = InvalidResourceHandle
  pred InsufficientDriver = NotReady
  pred SetOnActiveProcess = InsufficientDriver
  pred InvalidSurface = SetOnActiveProcess
  pred NoDevice = InvalidSurface
  pred ECCUncorrectable = NoDevice
  pred SharedObjectSymbolNotFound = ECCUncorrectable
  pred SharedObjectInitFailed = SharedObjectSymbolNotFound
  pred UnsupportedLimit = SharedObjectInitFailed
  pred DuplicateVariableName = UnsupportedLimit
  pred DuplicateTextureName = DuplicateVariableName
  pred DuplicateSurfaceName = DuplicateTextureName
  pred DevicesUnavailable = DuplicateSurfaceName
  pred InvalidKernelImage = DevicesUnavailable
  pred NoKernelImageForDevice = InvalidKernelImage
  pred IncompatibleDriverContext = NoKernelImageForDevice
  pred PeerAccessAlreadyEnabled = IncompatibleDriverContext
  pred PeerAccessNotEnabled = PeerAccessAlreadyEnabled
  pred DeviceAlreadyInUse = PeerAccessNotEnabled
  pred ProfilerDisabled = DeviceAlreadyInUse
  pred ProfilerNotInitialized = ProfilerDisabled
  pred ProfilerAlreadyStarted = ProfilerNotInitialized
  pred ProfilerAlreadyStopped = ProfilerAlreadyStarted
  pred Assert = ProfilerAlreadyStopped
  pred TooManyPeers = Assert
  pred HostMemoryAlreadyRegistered = TooManyPeers
  pred HostMemoryNotRegistered = HostMemoryAlreadyRegistered
  pred OperatingSystem = HostMemoryNotRegistered
  pred PeerAccessUnsupported = OperatingSystem
  pred LaunchMaxDepthExceeded = PeerAccessUnsupported
  pred LaunchFileScopedTex = LaunchMaxDepthExceeded
  pred LaunchFileScopedSurf = LaunchFileScopedTex
  pred SyncDepthExceeded = LaunchFileScopedSurf
  pred LaunchPendingCountExceeded = SyncDepthExceeded
  pred NotPermitted = LaunchPendingCountExceeded
  pred NotSupported = NotPermitted
  pred HardwareStackError = NotSupported
  pred IllegalInstruction = HardwareStackError
  pred MisalignedAddress = IllegalInstruction
  pred InvalidAddressSpace = MisalignedAddress
  pred InvalidPc = InvalidAddressSpace
  pred IllegalAddress = InvalidPc
  pred InvalidPtx = IllegalAddress
  pred InvalidGraphicsContext = InvalidPtx
  pred NvlinkUncorrectable = InvalidGraphicsContext
  pred StartupFailure = NvlinkUncorrectable
  pred ApiFailureBase = StartupFailure
  pred Success = error "Status.pred: Success 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 from = enumFromTo from ApiFailureBase

  fromEnum Success = 0
  fromEnum MissingConfiguration = 1
  fromEnum MemoryAllocation = 2
  fromEnum InitializationError = 3
  fromEnum LaunchFailure = 4
  fromEnum PriorLaunchFailure = 5
  fromEnum LaunchTimeout = 6
  fromEnum LaunchOutOfResources = 7
  fromEnum InvalidDeviceFunction = 8
  fromEnum InvalidConfiguration = 9
  fromEnum InvalidDevice = 10
  fromEnum InvalidValue = 11
  fromEnum InvalidPitchValue = 12
  fromEnum InvalidSymbol = 13
  fromEnum MapBufferObjectFailed = 14
  fromEnum UnmapBufferObjectFailed = 15
  fromEnum InvalidHostPointer = 16
  fromEnum InvalidDevicePointer = 17
  fromEnum InvalidTexture = 18
  fromEnum InvalidTextureBinding = 19
  fromEnum InvalidChannelDescriptor = 20
  fromEnum InvalidMemcpyDirection = 21
  fromEnum AddressOfConstant = 22
  fromEnum TextureFetchFailed = 23
  fromEnum TextureNotBound = 24
  fromEnum SynchronizationError = 25
  fromEnum InvalidFilterSetting = 26
  fromEnum InvalidNormSetting = 27
  fromEnum MixedDeviceExecution = 28
  fromEnum CudartUnloading = 29
  fromEnum Unknown = 30
  fromEnum NotYetImplemented = 31
  fromEnum MemoryValueTooLarge = 32
  fromEnum InvalidResourceHandle = 33
  fromEnum NotReady = 34
  fromEnum InsufficientDriver = 35
  fromEnum SetOnActiveProcess = 36
  fromEnum InvalidSurface = 37
  fromEnum NoDevice = 38
  fromEnum ECCUncorrectable = 39
  fromEnum SharedObjectSymbolNotFound = 40
  fromEnum SharedObjectInitFailed = 41
  fromEnum UnsupportedLimit = 42
  fromEnum DuplicateVariableName = 43
  fromEnum DuplicateTextureName = 44
  fromEnum DuplicateSurfaceName = 45
  fromEnum DevicesUnavailable = 46
  fromEnum InvalidKernelImage = 47
  fromEnum NoKernelImageForDevice = 48
  fromEnum IncompatibleDriverContext = 49
  fromEnum PeerAccessAlreadyEnabled = 50
  fromEnum PeerAccessNotEnabled = 51
  fromEnum DeviceAlreadyInUse = 54
  fromEnum ProfilerDisabled = 55
  fromEnum ProfilerNotInitialized = 56
  fromEnum ProfilerAlreadyStarted = 57
  fromEnum ProfilerAlreadyStopped = 58
  fromEnum Assert = 59
  fromEnum TooManyPeers = 60
  fromEnum HostMemoryAlreadyRegistered = 61
  fromEnum HostMemoryNotRegistered = 62
  fromEnum OperatingSystem = 63
  fromEnum PeerAccessUnsupported = 64
  fromEnum LaunchMaxDepthExceeded = 65
  fromEnum LaunchFileScopedTex = 66
  fromEnum LaunchFileScopedSurf = 67
  fromEnum SyncDepthExceeded = 68
  fromEnum LaunchPendingCountExceeded = 69
  fromEnum NotPermitted = 70
  fromEnum NotSupported = 71
  fromEnum HardwareStackError = 72
  fromEnum IllegalInstruction = 73
  fromEnum MisalignedAddress = 74
  fromEnum InvalidAddressSpace = 75
  fromEnum InvalidPc = 76
  fromEnum IllegalAddress = 77
  fromEnum InvalidPtx = 78
  fromEnum InvalidGraphicsContext = 79
  fromEnum NvlinkUncorrectable = 80
  fromEnum StartupFailure = 127
  fromEnum ApiFailureBase = 10000

  toEnum 0 = Success
  toEnum 1 = MissingConfiguration
  toEnum 2 = MemoryAllocation
  toEnum 3 = InitializationError
  toEnum 4 = LaunchFailure
  toEnum 5 = PriorLaunchFailure
  toEnum 6 = LaunchTimeout
  toEnum 7 = LaunchOutOfResources
  toEnum 8 = InvalidDeviceFunction
  toEnum 9 = InvalidConfiguration
  toEnum 10 = InvalidDevice
  toEnum 11 = InvalidValue
  toEnum 12 = InvalidPitchValue
  toEnum 13 = InvalidSymbol
  toEnum 14 = MapBufferObjectFailed
  toEnum 15 = UnmapBufferObjectFailed
  toEnum 16 = InvalidHostPointer
  toEnum 17 = InvalidDevicePointer
  toEnum 18 = InvalidTexture
  toEnum 19 = InvalidTextureBinding
  toEnum 20 = InvalidChannelDescriptor
  toEnum 21 = InvalidMemcpyDirection
  toEnum 22 = AddressOfConstant
  toEnum 23 = TextureFetchFailed
  toEnum 24 = TextureNotBound
  toEnum 25 = SynchronizationError
  toEnum 26 = InvalidFilterSetting
  toEnum 27 = InvalidNormSetting
  toEnum 28 = MixedDeviceExecution
  toEnum 29 = CudartUnloading
  toEnum 30 = Unknown
  toEnum 31 = NotYetImplemented
  toEnum 32 = MemoryValueTooLarge
  toEnum 33 = InvalidResourceHandle
  toEnum 34 = NotReady
  toEnum 35 = InsufficientDriver
  toEnum 36 = SetOnActiveProcess
  toEnum 37 = InvalidSurface
  toEnum 38 = NoDevice
  toEnum 39 = ECCUncorrectable
  toEnum 40 = SharedObjectSymbolNotFound
  toEnum 41 = SharedObjectInitFailed
  toEnum 42 = UnsupportedLimit
  toEnum 43 = DuplicateVariableName
  toEnum 44 = DuplicateTextureName
  toEnum 45 = DuplicateSurfaceName
  toEnum 46 = DevicesUnavailable
  toEnum 47 = InvalidKernelImage
  toEnum 48 = NoKernelImageForDevice
  toEnum 49 = IncompatibleDriverContext
  toEnum 50 = PeerAccessAlreadyEnabled
  toEnum 51 = PeerAccessNotEnabled
  toEnum 54 = DeviceAlreadyInUse
  toEnum 55 = ProfilerDisabled
  toEnum 56 = ProfilerNotInitialized
  toEnum 57 = ProfilerAlreadyStarted
  toEnum 58 = ProfilerAlreadyStopped
  toEnum 59 = Assert
  toEnum 60 = TooManyPeers
  toEnum 61 = HostMemoryAlreadyRegistered
  toEnum 62 = HostMemoryNotRegistered
  toEnum 63 = OperatingSystem
  toEnum 64 = PeerAccessUnsupported
  toEnum 65 = LaunchMaxDepthExceeded
  toEnum 66 = LaunchFileScopedTex
  toEnum 67 = LaunchFileScopedSurf
  toEnum 68 = SyncDepthExceeded
  toEnum 69 = LaunchPendingCountExceeded
  toEnum 70 = NotPermitted
  toEnum 71 = NotSupported
  toEnum 72 = HardwareStackError
  toEnum 73 = IllegalInstruction
  toEnum 74 = MisalignedAddress
  toEnum 75 = InvalidAddressSpace
  toEnum 76 = InvalidPc
  toEnum 77 = IllegalAddress
  toEnum 78 = InvalidPtx
  toEnum 79 = InvalidGraphicsContext
  toEnum 80 = NvlinkUncorrectable
  toEnum 127 = StartupFailure
  toEnum 10000 = ApiFailureBase
  toEnum unmatched = error ("Status.toEnum: Cannot match " ++ show unmatched)

{-# LINE 49 "src/Foreign/CUDA/Runtime/Error.chs" #-}


--------------------------------------------------------------------------------
-- 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' in the IO Monad
--
cudaError :: String -> IO a
cudaError s = throwIO (UserError s)

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


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

-- |
-- Return the descriptive string associated with a particular error code
--
instance Describe Status where
    describe = cudaGetErrorString

-- Logically, this must be a pure function, returning a pointer to a statically
-- defined string constant.
--
cudaGetErrorString :: (Status) -> (String)
cudaGetErrorString a1 =
  C2HSImp.unsafePerformIO $
  let {a1' = cFromEnum a1} in 
  cudaGetErrorString'_ a1' >>= \res ->
  C2HSImp.peekCString res >>= \res' ->
  return (res')

{-# LINE 94 "src/Foreign/CUDA/Runtime/Error.chs" #-}



-- |
-- Return the results of a function on successful execution, otherwise return
-- the 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)


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


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