-- 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/Driver/Device.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE EmptyCase                #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Device
-- Copyright : [2009..2017] Trevor L. McDonell
-- License   : BSD
--
-- Device management for low-level driver interface
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Device (

  -- * Device Management
  Device(..),
  DeviceProperties(..), DeviceAttribute(..), Compute(..), ComputeMode(..), InitFlag,
  initialise, capability, device, attribute, count, name, props, totalMem

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





{-# LINE 28 "src/Foreign/CUDA/Driver/Device.chs" #-}


-- Friends
import Foreign.CUDA.Analysis.Device
import Foreign.CUDA.Driver.Error
import Foreign.CUDA.Internal.C2HS

-- System
import Foreign
import Foreign.C
import Control.Monad                                    ( liftM )
import Control.Applicative
import Prelude


--------------------------------------------------------------------------------
-- Data Types
--------------------------------------------------------------------------------

-- |
-- A CUDA device
--
newtype Device = Device { useDevice :: (C2HSImp.CInt)}
  deriving (Eq, Show)


-- |
-- Device attributes
--
data DeviceAttribute = MaxThreadsPerBlock
                     | MaxBlockDimX
                     | MaxBlockDimY
                     | MaxBlockDimZ
                     | MaxGridDimX
                     | MaxGridDimY
                     | MaxGridDimZ
                     | MaxSharedMemoryPerBlock
                     | SharedMemoryPerBlock
                     | TotalConstantMemory
                     | WarpSize
                     | MaxPitch
                     | MaxRegistersPerBlock
                     | RegistersPerBlock
                     | ClockRate
                     | TextureAlignment
                     | GpuOverlap
                     | MultiprocessorCount
                     | KernelExecTimeout
                     | Integrated
                     | CanMapHostMemory
                     | ComputeMode
                     | MaximumTexture1dWidth
                     | MaximumTexture2dWidth
                     | MaximumTexture2dHeight
                     | MaximumTexture3dWidth
                     | MaximumTexture3dHeight
                     | MaximumTexture3dDepth
                     | MaximumTexture2dLayeredWidth
                     | MaximumTexture2dArrayWidth
                     | MaximumTexture2dLayeredHeight
                     | MaximumTexture2dArrayHeight
                     | MaximumTexture2dLayeredLayers
                     | MaximumTexture2dArrayNumslices
                     | SurfaceAlignment
                     | ConcurrentKernels
                     | EccEnabled
                     | PciBusId
                     | PciDeviceId
                     | TccDriver
                     | MemoryClockRate
                     | GlobalMemoryBusWidth
                     | L2CacheSize
                     | MaxThreadsPerMultiprocessor
                     | AsyncEngineCount
                     | UnifiedAddressing
                     | MaximumTexture1dLayeredWidth
                     | MaximumTexture1dLayeredLayers
                     | CanTex2dGather
                     | MaximumTexture2dGatherWidth
                     | MaximumTexture2dGatherHeight
                     | MaximumTexture3dWidthAlternate
                     | MaximumTexture3dHeightAlternate
                     | MaximumTexture3dDepthAlternate
                     | PciDomainId
                     | TexturePitchAlignment
                     | MaximumTexturecubemapWidth
                     | MaximumTexturecubemapLayeredWidth
                     | MaximumTexturecubemapLayeredLayers
                     | MaximumSurface1dWidth
                     | MaximumSurface2dWidth
                     | MaximumSurface2dHeight
                     | MaximumSurface3dWidth
                     | MaximumSurface3dHeight
                     | MaximumSurface3dDepth
                     | MaximumSurface1dLayeredWidth
                     | MaximumSurface1dLayeredLayers
                     | MaximumSurface2dLayeredWidth
                     | MaximumSurface2dLayeredHeight
                     | MaximumSurface2dLayeredLayers
                     | MaximumSurfacecubemapWidth
                     | MaximumSurfacecubemapLayeredWidth
                     | MaximumSurfacecubemapLayeredLayers
                     | MaximumTexture1dLinearWidth
                     | MaximumTexture2dLinearWidth
                     | MaximumTexture2dLinearHeight
                     | MaximumTexture2dLinearPitch
                     | MaximumTexture2dMipmappedWidth
                     | MaximumTexture2dMipmappedHeight
                     | ComputeCapabilityMajor
                     | ComputeCapabilityMinor
                     | MaximumTexture1dMipmappedWidth
                     | StreamPrioritiesSupported
                     | GlobalL1CacheSupported
                     | LocalL1CacheSupported
                     | MaxSharedMemoryPerMultiprocessor
                     | MaxRegistersPerMultiprocessor
                     | ManagedMemory
                     | MultiGpuBoard
                     | MultiGpuBoardGroupId
                     | HostNativeAtomicSupported
                     | SingleToDoublePrecisionPerfRatio
                     | PageableMemoryAccess
                     | ConcurrentManagedAccess
                     | ComputePreemptionSupported
                     | CanUseHostPointerForRegisteredMem
                     | CU_DEVICE_ATTRIBUTE_MAX
  deriving (Eq,Show)
instance Enum DeviceAttribute where
  succ MaxThreadsPerBlock = MaxBlockDimX
  succ MaxBlockDimX = MaxBlockDimY
  succ MaxBlockDimY = MaxBlockDimZ
  succ MaxBlockDimZ = MaxGridDimX
  succ MaxGridDimX = MaxGridDimY
  succ MaxGridDimY = MaxGridDimZ
  succ MaxGridDimZ = MaxSharedMemoryPerBlock
  succ MaxSharedMemoryPerBlock = TotalConstantMemory
  succ SharedMemoryPerBlock = TotalConstantMemory
  succ TotalConstantMemory = WarpSize
  succ WarpSize = MaxPitch
  succ MaxPitch = MaxRegistersPerBlock
  succ MaxRegistersPerBlock = ClockRate
  succ RegistersPerBlock = ClockRate
  succ ClockRate = TextureAlignment
  succ TextureAlignment = GpuOverlap
  succ GpuOverlap = MultiprocessorCount
  succ MultiprocessorCount = KernelExecTimeout
  succ KernelExecTimeout = Integrated
  succ Integrated = CanMapHostMemory
  succ CanMapHostMemory = ComputeMode
  succ ComputeMode = MaximumTexture1dWidth
  succ MaximumTexture1dWidth = MaximumTexture2dWidth
  succ MaximumTexture2dWidth = MaximumTexture2dHeight
  succ MaximumTexture2dHeight = MaximumTexture3dWidth
  succ MaximumTexture3dWidth = MaximumTexture3dHeight
  succ MaximumTexture3dHeight = MaximumTexture3dDepth
  succ MaximumTexture3dDepth = MaximumTexture2dLayeredWidth
  succ MaximumTexture2dLayeredWidth = MaximumTexture2dLayeredHeight
  succ MaximumTexture2dArrayWidth = MaximumTexture2dLayeredHeight
  succ MaximumTexture2dLayeredHeight = MaximumTexture2dLayeredLayers
  succ MaximumTexture2dArrayHeight = MaximumTexture2dLayeredLayers
  succ MaximumTexture2dLayeredLayers = SurfaceAlignment
  succ MaximumTexture2dArrayNumslices = SurfaceAlignment
  succ SurfaceAlignment = ConcurrentKernels
  succ ConcurrentKernels = EccEnabled
  succ EccEnabled = PciBusId
  succ PciBusId = PciDeviceId
  succ PciDeviceId = TccDriver
  succ TccDriver = MemoryClockRate
  succ MemoryClockRate = GlobalMemoryBusWidth
  succ GlobalMemoryBusWidth = L2CacheSize
  succ L2CacheSize = MaxThreadsPerMultiprocessor
  succ MaxThreadsPerMultiprocessor = AsyncEngineCount
  succ AsyncEngineCount = UnifiedAddressing
  succ UnifiedAddressing = MaximumTexture1dLayeredWidth
  succ MaximumTexture1dLayeredWidth = MaximumTexture1dLayeredLayers
  succ MaximumTexture1dLayeredLayers = CanTex2dGather
  succ CanTex2dGather = MaximumTexture2dGatherWidth
  succ MaximumTexture2dGatherWidth = MaximumTexture2dGatherHeight
  succ MaximumTexture2dGatherHeight = MaximumTexture3dWidthAlternate
  succ MaximumTexture3dWidthAlternate = MaximumTexture3dHeightAlternate
  succ MaximumTexture3dHeightAlternate = MaximumTexture3dDepthAlternate
  succ MaximumTexture3dDepthAlternate = PciDomainId
  succ PciDomainId = TexturePitchAlignment
  succ TexturePitchAlignment = MaximumTexturecubemapWidth
  succ MaximumTexturecubemapWidth = MaximumTexturecubemapLayeredWidth
  succ MaximumTexturecubemapLayeredWidth = MaximumTexturecubemapLayeredLayers
  succ MaximumTexturecubemapLayeredLayers = MaximumSurface1dWidth
  succ MaximumSurface1dWidth = MaximumSurface2dWidth
  succ MaximumSurface2dWidth = MaximumSurface2dHeight
  succ MaximumSurface2dHeight = MaximumSurface3dWidth
  succ MaximumSurface3dWidth = MaximumSurface3dHeight
  succ MaximumSurface3dHeight = MaximumSurface3dDepth
  succ MaximumSurface3dDepth = MaximumSurface1dLayeredWidth
  succ MaximumSurface1dLayeredWidth = MaximumSurface1dLayeredLayers
  succ MaximumSurface1dLayeredLayers = MaximumSurface2dLayeredWidth
  succ MaximumSurface2dLayeredWidth = MaximumSurface2dLayeredHeight
  succ MaximumSurface2dLayeredHeight = MaximumSurface2dLayeredLayers
  succ MaximumSurface2dLayeredLayers = MaximumSurfacecubemapWidth
  succ MaximumSurfacecubemapWidth = MaximumSurfacecubemapLayeredWidth
  succ MaximumSurfacecubemapLayeredWidth = MaximumSurfacecubemapLayeredLayers
  succ MaximumSurfacecubemapLayeredLayers = MaximumTexture1dLinearWidth
  succ MaximumTexture1dLinearWidth = MaximumTexture2dLinearWidth
  succ MaximumTexture2dLinearWidth = MaximumTexture2dLinearHeight
  succ MaximumTexture2dLinearHeight = MaximumTexture2dLinearPitch
  succ MaximumTexture2dLinearPitch = MaximumTexture2dMipmappedWidth
  succ MaximumTexture2dMipmappedWidth = MaximumTexture2dMipmappedHeight
  succ MaximumTexture2dMipmappedHeight = ComputeCapabilityMajor
  succ ComputeCapabilityMajor = ComputeCapabilityMinor
  succ ComputeCapabilityMinor = MaximumTexture1dMipmappedWidth
  succ MaximumTexture1dMipmappedWidth = StreamPrioritiesSupported
  succ StreamPrioritiesSupported = GlobalL1CacheSupported
  succ GlobalL1CacheSupported = LocalL1CacheSupported
  succ LocalL1CacheSupported = MaxSharedMemoryPerMultiprocessor
  succ MaxSharedMemoryPerMultiprocessor = MaxRegistersPerMultiprocessor
  succ MaxRegistersPerMultiprocessor = ManagedMemory
  succ ManagedMemory = MultiGpuBoard
  succ MultiGpuBoard = MultiGpuBoardGroupId
  succ MultiGpuBoardGroupId = HostNativeAtomicSupported
  succ HostNativeAtomicSupported = SingleToDoublePrecisionPerfRatio
  succ SingleToDoublePrecisionPerfRatio = PageableMemoryAccess
  succ PageableMemoryAccess = ConcurrentManagedAccess
  succ ConcurrentManagedAccess = ComputePreemptionSupported
  succ ComputePreemptionSupported = CanUseHostPointerForRegisteredMem
  succ CanUseHostPointerForRegisteredMem = CU_DEVICE_ATTRIBUTE_MAX
  succ CU_DEVICE_ATTRIBUTE_MAX = error "DeviceAttribute.succ: CU_DEVICE_ATTRIBUTE_MAX has no successor"

  pred MaxBlockDimX = MaxThreadsPerBlock
  pred MaxBlockDimY = MaxBlockDimX
  pred MaxBlockDimZ = MaxBlockDimY
  pred MaxGridDimX = MaxBlockDimZ
  pred MaxGridDimY = MaxGridDimX
  pred MaxGridDimZ = MaxGridDimY
  pred MaxSharedMemoryPerBlock = MaxGridDimZ
  pred SharedMemoryPerBlock = MaxGridDimZ
  pred TotalConstantMemory = MaxSharedMemoryPerBlock
  pred WarpSize = TotalConstantMemory
  pred MaxPitch = WarpSize
  pred MaxRegistersPerBlock = MaxPitch
  pred RegistersPerBlock = MaxPitch
  pred ClockRate = MaxRegistersPerBlock
  pred TextureAlignment = ClockRate
  pred GpuOverlap = TextureAlignment
  pred MultiprocessorCount = GpuOverlap
  pred KernelExecTimeout = MultiprocessorCount
  pred Integrated = KernelExecTimeout
  pred CanMapHostMemory = Integrated
  pred ComputeMode = CanMapHostMemory
  pred MaximumTexture1dWidth = ComputeMode
  pred MaximumTexture2dWidth = MaximumTexture1dWidth
  pred MaximumTexture2dHeight = MaximumTexture2dWidth
  pred MaximumTexture3dWidth = MaximumTexture2dHeight
  pred MaximumTexture3dHeight = MaximumTexture3dWidth
  pred MaximumTexture3dDepth = MaximumTexture3dHeight
  pred MaximumTexture2dLayeredWidth = MaximumTexture3dDepth
  pred MaximumTexture2dArrayWidth = MaximumTexture3dDepth
  pred MaximumTexture2dLayeredHeight = MaximumTexture2dLayeredWidth
  pred MaximumTexture2dArrayHeight = MaximumTexture2dLayeredWidth
  pred MaximumTexture2dLayeredLayers = MaximumTexture2dLayeredHeight
  pred MaximumTexture2dArrayNumslices = MaximumTexture2dLayeredHeight
  pred SurfaceAlignment = MaximumTexture2dLayeredLayers
  pred ConcurrentKernels = SurfaceAlignment
  pred EccEnabled = ConcurrentKernels
  pred PciBusId = EccEnabled
  pred PciDeviceId = PciBusId
  pred TccDriver = PciDeviceId
  pred MemoryClockRate = TccDriver
  pred GlobalMemoryBusWidth = MemoryClockRate
  pred L2CacheSize = GlobalMemoryBusWidth
  pred MaxThreadsPerMultiprocessor = L2CacheSize
  pred AsyncEngineCount = MaxThreadsPerMultiprocessor
  pred UnifiedAddressing = AsyncEngineCount
  pred MaximumTexture1dLayeredWidth = UnifiedAddressing
  pred MaximumTexture1dLayeredLayers = MaximumTexture1dLayeredWidth
  pred CanTex2dGather = MaximumTexture1dLayeredLayers
  pred MaximumTexture2dGatherWidth = CanTex2dGather
  pred MaximumTexture2dGatherHeight = MaximumTexture2dGatherWidth
  pred MaximumTexture3dWidthAlternate = MaximumTexture2dGatherHeight
  pred MaximumTexture3dHeightAlternate = MaximumTexture3dWidthAlternate
  pred MaximumTexture3dDepthAlternate = MaximumTexture3dHeightAlternate
  pred PciDomainId = MaximumTexture3dDepthAlternate
  pred TexturePitchAlignment = PciDomainId
  pred MaximumTexturecubemapWidth = TexturePitchAlignment
  pred MaximumTexturecubemapLayeredWidth = MaximumTexturecubemapWidth
  pred MaximumTexturecubemapLayeredLayers = MaximumTexturecubemapLayeredWidth
  pred MaximumSurface1dWidth = MaximumTexturecubemapLayeredLayers
  pred MaximumSurface2dWidth = MaximumSurface1dWidth
  pred MaximumSurface2dHeight = MaximumSurface2dWidth
  pred MaximumSurface3dWidth = MaximumSurface2dHeight
  pred MaximumSurface3dHeight = MaximumSurface3dWidth
  pred MaximumSurface3dDepth = MaximumSurface3dHeight
  pred MaximumSurface1dLayeredWidth = MaximumSurface3dDepth
  pred MaximumSurface1dLayeredLayers = MaximumSurface1dLayeredWidth
  pred MaximumSurface2dLayeredWidth = MaximumSurface1dLayeredLayers
  pred MaximumSurface2dLayeredHeight = MaximumSurface2dLayeredWidth
  pred MaximumSurface2dLayeredLayers = MaximumSurface2dLayeredHeight
  pred MaximumSurfacecubemapWidth = MaximumSurface2dLayeredLayers
  pred MaximumSurfacecubemapLayeredWidth = MaximumSurfacecubemapWidth
  pred MaximumSurfacecubemapLayeredLayers = MaximumSurfacecubemapLayeredWidth
  pred MaximumTexture1dLinearWidth = MaximumSurfacecubemapLayeredLayers
  pred MaximumTexture2dLinearWidth = MaximumTexture1dLinearWidth
  pred MaximumTexture2dLinearHeight = MaximumTexture2dLinearWidth
  pred MaximumTexture2dLinearPitch = MaximumTexture2dLinearHeight
  pred MaximumTexture2dMipmappedWidth = MaximumTexture2dLinearPitch
  pred MaximumTexture2dMipmappedHeight = MaximumTexture2dMipmappedWidth
  pred ComputeCapabilityMajor = MaximumTexture2dMipmappedHeight
  pred ComputeCapabilityMinor = ComputeCapabilityMajor
  pred MaximumTexture1dMipmappedWidth = ComputeCapabilityMinor
  pred StreamPrioritiesSupported = MaximumTexture1dMipmappedWidth
  pred GlobalL1CacheSupported = StreamPrioritiesSupported
  pred LocalL1CacheSupported = GlobalL1CacheSupported
  pred MaxSharedMemoryPerMultiprocessor = LocalL1CacheSupported
  pred MaxRegistersPerMultiprocessor = MaxSharedMemoryPerMultiprocessor
  pred ManagedMemory = MaxRegistersPerMultiprocessor
  pred MultiGpuBoard = ManagedMemory
  pred MultiGpuBoardGroupId = MultiGpuBoard
  pred HostNativeAtomicSupported = MultiGpuBoardGroupId
  pred SingleToDoublePrecisionPerfRatio = HostNativeAtomicSupported
  pred PageableMemoryAccess = SingleToDoublePrecisionPerfRatio
  pred ConcurrentManagedAccess = PageableMemoryAccess
  pred ComputePreemptionSupported = ConcurrentManagedAccess
  pred CanUseHostPointerForRegisteredMem = ComputePreemptionSupported
  pred CU_DEVICE_ATTRIBUTE_MAX = CanUseHostPointerForRegisteredMem
  pred MaxThreadsPerBlock = error "DeviceAttribute.pred: MaxThreadsPerBlock 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 CU_DEVICE_ATTRIBUTE_MAX

  fromEnum MaxThreadsPerBlock = 1
  fromEnum MaxBlockDimX = 2
  fromEnum MaxBlockDimY = 3
  fromEnum MaxBlockDimZ = 4
  fromEnum MaxGridDimX = 5
  fromEnum MaxGridDimY = 6
  fromEnum MaxGridDimZ = 7
  fromEnum MaxSharedMemoryPerBlock = 8
  fromEnum SharedMemoryPerBlock = 8
  fromEnum TotalConstantMemory = 9
  fromEnum WarpSize = 10
  fromEnum MaxPitch = 11
  fromEnum MaxRegistersPerBlock = 12
  fromEnum RegistersPerBlock = 12
  fromEnum ClockRate = 13
  fromEnum TextureAlignment = 14
  fromEnum GpuOverlap = 15
  fromEnum MultiprocessorCount = 16
  fromEnum KernelExecTimeout = 17
  fromEnum Integrated = 18
  fromEnum CanMapHostMemory = 19
  fromEnum ComputeMode = 20
  fromEnum MaximumTexture1dWidth = 21
  fromEnum MaximumTexture2dWidth = 22
  fromEnum MaximumTexture2dHeight = 23
  fromEnum MaximumTexture3dWidth = 24
  fromEnum MaximumTexture3dHeight = 25
  fromEnum MaximumTexture3dDepth = 26
  fromEnum MaximumTexture2dLayeredWidth = 27
  fromEnum MaximumTexture2dArrayWidth = 27
  fromEnum MaximumTexture2dLayeredHeight = 28
  fromEnum MaximumTexture2dArrayHeight = 28
  fromEnum MaximumTexture2dLayeredLayers = 29
  fromEnum MaximumTexture2dArrayNumslices = 29
  fromEnum SurfaceAlignment = 30
  fromEnum ConcurrentKernels = 31
  fromEnum EccEnabled = 32
  fromEnum PciBusId = 33
  fromEnum PciDeviceId = 34
  fromEnum TccDriver = 35
  fromEnum MemoryClockRate = 36
  fromEnum GlobalMemoryBusWidth = 37
  fromEnum L2CacheSize = 38
  fromEnum MaxThreadsPerMultiprocessor = 39
  fromEnum AsyncEngineCount = 40
  fromEnum UnifiedAddressing = 41
  fromEnum MaximumTexture1dLayeredWidth = 42
  fromEnum MaximumTexture1dLayeredLayers = 43
  fromEnum CanTex2dGather = 44
  fromEnum MaximumTexture2dGatherWidth = 45
  fromEnum MaximumTexture2dGatherHeight = 46
  fromEnum MaximumTexture3dWidthAlternate = 47
  fromEnum MaximumTexture3dHeightAlternate = 48
  fromEnum MaximumTexture3dDepthAlternate = 49
  fromEnum PciDomainId = 50
  fromEnum TexturePitchAlignment = 51
  fromEnum MaximumTexturecubemapWidth = 52
  fromEnum MaximumTexturecubemapLayeredWidth = 53
  fromEnum MaximumTexturecubemapLayeredLayers = 54
  fromEnum MaximumSurface1dWidth = 55
  fromEnum MaximumSurface2dWidth = 56
  fromEnum MaximumSurface2dHeight = 57
  fromEnum MaximumSurface3dWidth = 58
  fromEnum MaximumSurface3dHeight = 59
  fromEnum MaximumSurface3dDepth = 60
  fromEnum MaximumSurface1dLayeredWidth = 61
  fromEnum MaximumSurface1dLayeredLayers = 62
  fromEnum MaximumSurface2dLayeredWidth = 63
  fromEnum MaximumSurface2dLayeredHeight = 64
  fromEnum MaximumSurface2dLayeredLayers = 65
  fromEnum MaximumSurfacecubemapWidth = 66
  fromEnum MaximumSurfacecubemapLayeredWidth = 67
  fromEnum MaximumSurfacecubemapLayeredLayers = 68
  fromEnum MaximumTexture1dLinearWidth = 69
  fromEnum MaximumTexture2dLinearWidth = 70
  fromEnum MaximumTexture2dLinearHeight = 71
  fromEnum MaximumTexture2dLinearPitch = 72
  fromEnum MaximumTexture2dMipmappedWidth = 73
  fromEnum MaximumTexture2dMipmappedHeight = 74
  fromEnum ComputeCapabilityMajor = 75
  fromEnum ComputeCapabilityMinor = 76
  fromEnum MaximumTexture1dMipmappedWidth = 77
  fromEnum StreamPrioritiesSupported = 78
  fromEnum GlobalL1CacheSupported = 79
  fromEnum LocalL1CacheSupported = 80
  fromEnum MaxSharedMemoryPerMultiprocessor = 81
  fromEnum MaxRegistersPerMultiprocessor = 82
  fromEnum ManagedMemory = 83
  fromEnum MultiGpuBoard = 84
  fromEnum MultiGpuBoardGroupId = 85
  fromEnum HostNativeAtomicSupported = 86
  fromEnum SingleToDoublePrecisionPerfRatio = 87
  fromEnum PageableMemoryAccess = 88
  fromEnum ConcurrentManagedAccess = 89
  fromEnum ComputePreemptionSupported = 90
  fromEnum CanUseHostPointerForRegisteredMem = 91
  fromEnum CU_DEVICE_ATTRIBUTE_MAX = 92

  toEnum 1 = MaxThreadsPerBlock
  toEnum 2 = MaxBlockDimX
  toEnum 3 = MaxBlockDimY
  toEnum 4 = MaxBlockDimZ
  toEnum 5 = MaxGridDimX
  toEnum 6 = MaxGridDimY
  toEnum 7 = MaxGridDimZ
  toEnum 8 = MaxSharedMemoryPerBlock
  toEnum 9 = TotalConstantMemory
  toEnum 10 = WarpSize
  toEnum 11 = MaxPitch
  toEnum 12 = MaxRegistersPerBlock
  toEnum 13 = ClockRate
  toEnum 14 = TextureAlignment
  toEnum 15 = GpuOverlap
  toEnum 16 = MultiprocessorCount
  toEnum 17 = KernelExecTimeout
  toEnum 18 = Integrated
  toEnum 19 = CanMapHostMemory
  toEnum 20 = ComputeMode
  toEnum 21 = MaximumTexture1dWidth
  toEnum 22 = MaximumTexture2dWidth
  toEnum 23 = MaximumTexture2dHeight
  toEnum 24 = MaximumTexture3dWidth
  toEnum 25 = MaximumTexture3dHeight
  toEnum 26 = MaximumTexture3dDepth
  toEnum 27 = MaximumTexture2dLayeredWidth
  toEnum 28 = MaximumTexture2dLayeredHeight
  toEnum 29 = MaximumTexture2dLayeredLayers
  toEnum 30 = SurfaceAlignment
  toEnum 31 = ConcurrentKernels
  toEnum 32 = EccEnabled
  toEnum 33 = PciBusId
  toEnum 34 = PciDeviceId
  toEnum 35 = TccDriver
  toEnum 36 = MemoryClockRate
  toEnum 37 = GlobalMemoryBusWidth
  toEnum 38 = L2CacheSize
  toEnum 39 = MaxThreadsPerMultiprocessor
  toEnum 40 = AsyncEngineCount
  toEnum 41 = UnifiedAddressing
  toEnum 42 = MaximumTexture1dLayeredWidth
  toEnum 43 = MaximumTexture1dLayeredLayers
  toEnum 44 = CanTex2dGather
  toEnum 45 = MaximumTexture2dGatherWidth
  toEnum 46 = MaximumTexture2dGatherHeight
  toEnum 47 = MaximumTexture3dWidthAlternate
  toEnum 48 = MaximumTexture3dHeightAlternate
  toEnum 49 = MaximumTexture3dDepthAlternate
  toEnum 50 = PciDomainId
  toEnum 51 = TexturePitchAlignment
  toEnum 52 = MaximumTexturecubemapWidth
  toEnum 53 = MaximumTexturecubemapLayeredWidth
  toEnum 54 = MaximumTexturecubemapLayeredLayers
  toEnum 55 = MaximumSurface1dWidth
  toEnum 56 = MaximumSurface2dWidth
  toEnum 57 = MaximumSurface2dHeight
  toEnum 58 = MaximumSurface3dWidth
  toEnum 59 = MaximumSurface3dHeight
  toEnum 60 = MaximumSurface3dDepth
  toEnum 61 = MaximumSurface1dLayeredWidth
  toEnum 62 = MaximumSurface1dLayeredLayers
  toEnum 63 = MaximumSurface2dLayeredWidth
  toEnum 64 = MaximumSurface2dLayeredHeight
  toEnum 65 = MaximumSurface2dLayeredLayers
  toEnum 66 = MaximumSurfacecubemapWidth
  toEnum 67 = MaximumSurfacecubemapLayeredWidth
  toEnum 68 = MaximumSurfacecubemapLayeredLayers
  toEnum 69 = MaximumTexture1dLinearWidth
  toEnum 70 = MaximumTexture2dLinearWidth
  toEnum 71 = MaximumTexture2dLinearHeight
  toEnum 72 = MaximumTexture2dLinearPitch
  toEnum 73 = MaximumTexture2dMipmappedWidth
  toEnum 74 = MaximumTexture2dMipmappedHeight
  toEnum 75 = ComputeCapabilityMajor
  toEnum 76 = ComputeCapabilityMinor
  toEnum 77 = MaximumTexture1dMipmappedWidth
  toEnum 78 = StreamPrioritiesSupported
  toEnum 79 = GlobalL1CacheSupported
  toEnum 80 = LocalL1CacheSupported
  toEnum 81 = MaxSharedMemoryPerMultiprocessor
  toEnum 82 = MaxRegistersPerMultiprocessor
  toEnum 83 = ManagedMemory
  toEnum 84 = MultiGpuBoard
  toEnum 85 = MultiGpuBoardGroupId
  toEnum 86 = HostNativeAtomicSupported
  toEnum 87 = SingleToDoublePrecisionPerfRatio
  toEnum 88 = PageableMemoryAccess
  toEnum 89 = ConcurrentManagedAccess
  toEnum 90 = ComputePreemptionSupported
  toEnum 91 = CanUseHostPointerForRegisteredMem
  toEnum 92 = CU_DEVICE_ATTRIBUTE_MAX
  toEnum unmatched = error ("DeviceAttribute.toEnum: Cannot match " ++ show unmatched)

{-# LINE 60 "src/Foreign/CUDA/Driver/Device.chs" #-}





-- |
-- Possible option flags for CUDA initialisation. Dummy instance until the API
-- exports actual option values.
--
data InitFlag
instance Enum InitFlag where
  toEnum   x = case x of {}
  fromEnum x = case x of {}


--------------------------------------------------------------------------------
-- Initialisation
--------------------------------------------------------------------------------

-- |
-- Initialise the CUDA driver API. This must be called before any other
-- driver function.
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__INITIALIZE.html#group__CUDA__INITIALIZE_1g0a2f1517e1bd8502c7194c3a8c134bc3>
--
{-# INLINEABLE initialise #-}
initialise :: [InitFlag] -> IO ()
initialise !flags = nothingIfOk =<< cuInit flags <* enable_constructors

{-# INLINE enable_constructors #-}
enable_constructors :: IO ()
enable_constructors =
  enable_constructors'_ >>
  return ()

{-# LINE 147 "src/Foreign/CUDA/Driver/Device.chs" #-}


{-# INLINE cuInit #-}
cuInit :: ([InitFlag]) -> IO ((Status))
cuInit a1 =
  let {a1' = combineBitMasks a1} in 
  cuInit'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 151 "src/Foreign/CUDA/Driver/Device.chs" #-}



--------------------------------------------------------------------------------
-- Device Management
--------------------------------------------------------------------------------

-- |
-- Return the compute compatibility revision supported by the device
--
{-# INLINEABLE capability #-}
capability :: Device -> IO Compute
capability !dev =
  Compute <$> attribute dev ComputeCapabilityMajor
          <*> attribute dev ComputeCapabilityMinor


-- |
-- Return a handle to the compute device at the given ordinal.
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1g8bdd1cc7201304b01357b8034f6587cb>
--
{-# INLINEABLE device #-}
device :: Int -> IO Device
device !d = resultIfOk =<< cuDeviceGet d

{-# INLINE cuDeviceGet #-}
cuDeviceGet :: (Int) -> IO ((Status), (Device))
cuDeviceGet a2 =
  alloca $ \a1' -> 
  let {a2' = cIntConv a2} in 
  cuDeviceGet'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  dev  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 193 "src/Foreign/CUDA/Driver/Device.chs" #-}

  where dev = liftM Device . peek


-- |
-- Return the selected attribute for the given device.
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1g9c3e1414f0ad901d3278a4d6645fc266>
--
{-# INLINEABLE attribute #-}
attribute :: Device -> DeviceAttribute -> IO Int
attribute !d !a = resultIfOk =<< cuDeviceGetAttribute a d

{-# INLINE cuDeviceGetAttribute #-}
cuDeviceGetAttribute :: (DeviceAttribute) -> (Device) -> IO ((Status), (Int))
cuDeviceGetAttribute a2 a3 =
  alloca $ \a1' -> 
  let {a2' = cFromEnum a2} in 
  let {a3' = useDevice a3} in 
  cuDeviceGetAttribute'_ a1' a2' a3' >>= \res ->
  let {res' = cToEnum res} in
  peekIntConv  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 210 "src/Foreign/CUDA/Driver/Device.chs" #-}



-- |
-- Return the number of device with compute capability > 1.0.
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1g52b5ce05cb8c5fb6831b2c0ff2887c74>
--
{-# INLINEABLE count #-}
count :: IO Int
count = resultIfOk =<< cuDeviceGetCount

{-# INLINE cuDeviceGetCount #-}
cuDeviceGetCount :: IO ((Status), (Int))
cuDeviceGetCount =
  alloca $ \a1' -> 
  cuDeviceGetCount'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  peekIntConv  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 224 "src/Foreign/CUDA/Driver/Device.chs" #-}



-- |
-- The identifying name of the device.
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1gef75aa30df95446a845f2a7b9fffbb7f>
--
{-# INLINEABLE name #-}
name :: Device -> IO String
name !d = resultIfOk =<< cuDeviceGetName d

{-# INLINE cuDeviceGetName #-}
cuDeviceGetName :: (Device) -> IO ((Status), (String))
cuDeviceGetName a2 =
  allocaS $ \(a1'1, a1'2) -> 
  let {a2' = useDevice a2} in 
  cuDeviceGetName'_ a1'1  a1'2 a2' >>= \res ->
  let {res' = cToEnum res} in
  peekS  a1'1  a1'2>>= \a1'' -> 
  return (res', a1'')

{-# LINE 239 "src/Foreign/CUDA/Driver/Device.chs" #-}

  where
    len       = 512
    allocaS a = allocaBytes len $ \p -> a (p, cIntConv len)
    peekS s _ = peekCString s


-- |
-- Return the properties of the selected device
--
{-# INLINEABLE props #-}
props :: Device -> IO DeviceProperties
props !d = do

  cm  <- fromIntegral <$> attribute d TotalConstantMemory
  sm  <- fromIntegral <$> attribute d SharedMemoryPerBlock
  mp  <- fromIntegral <$> attribute d MaxPitch
  ta  <- fromIntegral <$> attribute d TextureAlignment
  cl  <- attribute d ClockRate
  ws  <- attribute d WarpSize
  rb  <- attribute d RegistersPerBlock
  tb  <- attribute d MaxThreadsPerBlock
  bs  <- (,,) <$> attribute d MaxBlockDimX
              <*> attribute d MaxBlockDimY
              <*> attribute d MaxBlockDimZ
  gs  <- (,,) <$> attribute d MaxGridDimX
              <*> attribute d MaxGridDimY
              <*> attribute d MaxGridDimZ

  -- The rest of the properties.
  --
  n   <- name d
  cc  <- capability d
  gm  <- totalMem d
  pc  <- attribute d MultiprocessorCount
  md  <- toEnum `fmap` attribute d ComputeMode
  ov  <- toBool `fmap` attribute d GpuOverlap
  ke  <- toBool `fmap` attribute d KernelExecTimeout
  tg  <- toBool `fmap` attribute d Integrated
  hm  <- toBool `fmap` attribute d CanMapHostMemory
  ck  <- toBool `fmap` attribute d ConcurrentKernels
  ee  <- toBool `fmap` attribute d EccEnabled
  u1  <- attribute d MaximumTexture1dWidth
  u21 <- attribute d MaximumTexture2dWidth
  u22 <- attribute d MaximumTexture2dHeight
  u31 <- attribute d MaximumTexture3dWidth
  u32 <- attribute d MaximumTexture3dHeight
  u33 <- attribute d MaximumTexture3dDepth
  ae  <- attribute d AsyncEngineCount
  l2  <- attribute d L2CacheSize
  tm  <- attribute d MaxThreadsPerMultiprocessor
  mw  <- attribute d GlobalMemoryBusWidth
  mc  <- attribute d MemoryClockRate
  pb  <- attribute d PciBusId
  pd  <- attribute d PciDeviceId
  pm  <- attribute d PciDomainId
  ua  <- toBool `fmap` attribute d UnifiedAddressing
  tcc <- toBool `fmap` attribute d TccDriver
  sp  <- toBool `fmap` attribute d StreamPrioritiesSupported
  gl1 <- toBool `fmap` attribute d GlobalL1CacheSupported
  ll1 <- toBool `fmap` attribute d LocalL1CacheSupported
  mm  <- toBool `fmap` attribute d ManagedMemory
  mg  <- toBool `fmap` attribute d MultiGpuBoard
  mid <- attribute d MultiGpuBoardGroupId

  return DeviceProperties
    {
      deviceName                        = n
    , computeCapability                 = cc
    , totalGlobalMem                    = gm
    , totalConstMem                     = cm
    , sharedMemPerBlock                 = sm
    , regsPerBlock                      = rb
    , warpSize                          = ws
    , maxThreadsPerBlock                = tb
    , maxBlockSize                      = bs
    , maxGridSize                       = gs
    , clockRate                         = cl
    , multiProcessorCount               = pc
    , memPitch                          = mp
    , textureAlignment                  = ta
    , computeMode                       = md
    , deviceOverlap                     = ov
    , kernelExecTimeoutEnabled          = ke
    , integrated                        = tg
    , canMapHostMemory                  = hm
    , concurrentKernels                 = ck
    , eccEnabled                        = ee
    , maxTextureDim1D                   = u1
    , maxTextureDim2D                   = (u21,u22)
    , maxTextureDim3D                   = (u31,u32,u33)
    , asyncEngineCount                  = ae
    , cacheMemL2                        = l2
    , maxThreadsPerMultiProcessor       = tm
    , memBusWidth                       = mw
    , memClockRate                      = mc
    , pciInfo                           = PCI pb pd pm
    , tccDriverEnabled                  = tcc
    , unifiedAddressing                 = ua
    , streamPriorities                  = sp
    , globalL1Cache                     = gl1
    , localL1Cache                      = ll1
    , managedMemory                     = mm
    , multiGPUBoard                     = mg
    , multiGPUBoardGroupID              = mid
    }



-- |
-- The total memory available on the device (bytes).
--
-- <http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1gc6a0d6551335a3780f9f3c967a0fde5d>
--
{-# INLINEABLE totalMem #-}
totalMem :: Device -> IO Int64
totalMem !d = resultIfOk =<< cuDeviceTotalMem d

{-# INLINE cuDeviceTotalMem #-}
cuDeviceTotalMem :: (Device) -> IO ((Status), (Int64))
cuDeviceTotalMem a2 =
  alloca $ \a1' -> 
  let {a2' = useDevice a2} in 
  cuDeviceTotalMem'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  peekIntConv  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 402 "src/Foreign/CUDA/Driver/Device.chs" #-}



foreign import ccall unsafe "Foreign/CUDA/Driver/Device.chs.h enable_constructors"
  enable_constructors'_ :: (IO ())

foreign import ccall unsafe "Foreign/CUDA/Driver/Device.chs.h cuInit"
  cuInit'_ :: (C2HSImp.CUInt -> (IO C2HSImp.CInt))

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

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

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

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

foreign import ccall unsafe "Foreign/CUDA/Driver/Device.chs.h cuDeviceTotalMem"
  cuDeviceTotalMem'_ :: ((C2HSImp.Ptr C2HSImp.CULong) -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))