-- 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/Device.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE RecordWildCards          #-}
{-# LANGUAGE TemplateHaskell          #-}
{-# LANGUAGE EmptyCase                #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Device
-- Copyright : [2009..2018] 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, uuid, totalMem,

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





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


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

-- System
import Control.Applicative
import Control.Monad                                    ( liftM )
import Data.Bits
import Data.UUID.Types
import Foreign
import Foreign.C
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
                     | CanUseStreamMemOps
                     | CanUse64BitStreamMemOps
                     | CanUseStreamWaitValueNor
                     | CooperativeLaunch
                     | CooperativeMultiDeviceLaunch
                     | MaxSharedMemoryPerBlockOptin
                     | CanFlushRemoteWrites
                     | HostRegisterSupported
                     | PageableMemoryAccessUsesHostPageTables
                     | DirectManagedMemAccessFromHost
                     | 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 = CanUseStreamMemOps
  succ CanUseStreamMemOps = CanUse64BitStreamMemOps
  succ CanUse64BitStreamMemOps = CanUseStreamWaitValueNor
  succ CanUseStreamWaitValueNor = CooperativeLaunch
  succ CooperativeLaunch = CooperativeMultiDeviceLaunch
  succ CooperativeMultiDeviceLaunch = MaxSharedMemoryPerBlockOptin
  succ MaxSharedMemoryPerBlockOptin = CanFlushRemoteWrites
  succ CanFlushRemoteWrites = HostRegisterSupported
  succ HostRegisterSupported = PageableMemoryAccessUsesHostPageTables
  succ PageableMemoryAccessUsesHostPageTables = DirectManagedMemAccessFromHost
  succ DirectManagedMemAccessFromHost = 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 CanUseStreamMemOps = CanUseHostPointerForRegisteredMem
  pred CanUse64BitStreamMemOps = CanUseStreamMemOps
  pred CanUseStreamWaitValueNor = CanUse64BitStreamMemOps
  pred CooperativeLaunch = CanUseStreamWaitValueNor
  pred CooperativeMultiDeviceLaunch = CooperativeLaunch
  pred MaxSharedMemoryPerBlockOptin = CooperativeMultiDeviceLaunch
  pred CanFlushRemoteWrites = MaxSharedMemoryPerBlockOptin
  pred HostRegisterSupported = CanFlushRemoteWrites
  pred PageableMemoryAccessUsesHostPageTables = HostRegisterSupported
  pred DirectManagedMemAccessFromHost = PageableMemoryAccessUsesHostPageTables
  pred CU_DEVICE_ATTRIBUTE_MAX = DirectManagedMemAccessFromHost
  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 CanUseStreamMemOps = 92
  fromEnum CanUse64BitStreamMemOps = 93
  fromEnum CanUseStreamWaitValueNor = 94
  fromEnum CooperativeLaunch = 95
  fromEnum CooperativeMultiDeviceLaunch = 96
  fromEnum MaxSharedMemoryPerBlockOptin = 97
  fromEnum CanFlushRemoteWrites = 98
  fromEnum HostRegisterSupported = 99
  fromEnum PageableMemoryAccessUsesHostPageTables = 100
  fromEnum DirectManagedMemAccessFromHost = 101
  fromEnum CU_DEVICE_ATTRIBUTE_MAX = 102

  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 = CanUseStreamMemOps
  toEnum 93 = CanUse64BitStreamMemOps
  toEnum 94 = CanUseStreamWaitValueNor
  toEnum 95 = CooperativeLaunch
  toEnum 96 = CooperativeMultiDeviceLaunch
  toEnum 97 = MaxSharedMemoryPerBlockOptin
  toEnum 98 = CanFlushRemoteWrites
  toEnum 99 = HostRegisterSupported
  toEnum 100 = PageableMemoryAccessUsesHostPageTables
  toEnum 101 = DirectManagedMemAccessFromHost
  toEnum 102 = CU_DEVICE_ATTRIBUTE_MAX
  toEnum unmatched = error ("DeviceAttribute.toEnum: Cannot match " ++ show unmatched)

{-# LINE 64 "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 = error ("InitFlag.toEnum: Cannot match " ++ show x)
  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 = do
  enable_constructors
  cuInit flags

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

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


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

{-# LINE 157 "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 a2 =
  alloca $ \a1' ->
  let {a2' = fromIntegral a2} in
  device'_ a1' a2' >>= \res ->
  checkStatus res >>
  dev  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 198 "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 = cuDeviceGetAttribute a d
  where
    cuDeviceGetAttribute :: (DeviceAttribute) -> (Device) -> IO ((Int))
    cuDeviceGetAttribute a2 a3 =
      alloca $ \a1' ->
      let {a2' = cFromEnum a2} in
      let {a3' = useDevice a3} in
      cuDeviceGetAttribute'_ a1' a2' a3' >>= \res ->
      checkStatus res >>
      peekIntConv  a1'>>= \a1'' ->
      return (a1'')

{-# LINE 217 "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 =
  alloca $ \a1' ->
  count'_ a1' >>= \res ->
  checkStatus res >>
  peekIntConv  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 229 "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 a2 =
  allocaS $ \(a1'1, a1'2) ->
  let {a2' = useDevice a2} in
  name'_ a1'1  a1'2 a2' >>= \res ->
  checkStatus res >>
  peekS  a1'1  a1'2>>= \a1'' ->
  return (a1'')

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

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


-- | Returns a UUID for the device
--
-- Requires CUDA-9.2
--
-- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1g987b46b884c101ed5be414ab4d9e60e4>
--
-- @since 0.10.0.0
--
{-# INLINE uuid #-}
uuid :: Device -> IO UUID
uuid !dev =
  allocaBytes 16 $ \ptr -> do
    cuDeviceGetUuid ptr dev
    unpack ptr
  where
    {-# INLINE cuDeviceGetUuid #-}
    cuDeviceGetUuid :: (Ptr ()) -> (Device) -> IO ()
    cuDeviceGetUuid a1 a2 =
      let {a1' = id a1} in
      let {a2' = useDevice a2} in
      cuDeviceGetUuid'_ a1' a2' >>= \res ->
      checkStatus res >>
      return ()

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


    {-# INLINE unpack #-}
    unpack :: Ptr () -> IO UUID
    unpack !p = do
      let !q = castPtr p
      a <- word <$> peekElemOff q  0 <*> peekElemOff q  1 <*> peekElemOff q  2 <*> peekElemOff q  3
      b <- word <$> peekElemOff q  4 <*> peekElemOff q  5 <*> peekElemOff q  6 <*> peekElemOff q  7
      c <- word <$> peekElemOff q  8 <*> peekElemOff q  9 <*> peekElemOff q 10 <*> peekElemOff q 11
      d <- word <$> peekElemOff q 12 <*> peekElemOff q 13 <*> peekElemOff q 14 <*> peekElemOff q 15
      return $! fromWords a b c d

    {-# INLINE word #-}
    word :: Word8 -> Word8 -> Word8 -> Word8 -> Word32
    word !a !b !c !d
      =  (fromIntegral a `shiftL` 24)
     .|. (fromIntegral b `shiftL` 16)
     .|. (fromIntegral c `shiftL`  8)
     .|. (fromIntegral d            )


-- TODO: cuDeviceGetLuid, introduced CUDA-10.0 (windows only)

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

  totalConstMem         <- fromIntegral <$> attribute d TotalConstantMemory
  sharedMemPerBlock     <- fromIntegral <$> attribute d SharedMemoryPerBlock
  memPitch              <- fromIntegral <$> attribute d MaxPitch
  textureAlignment      <- fromIntegral <$> attribute d TextureAlignment
  clockRate             <- attribute d ClockRate
  warpSize              <- attribute d WarpSize
  regsPerBlock          <- attribute d RegistersPerBlock
  maxThreadsPerBlock    <- attribute d MaxThreadsPerBlock
  maxBlockSize          <- (,,) <$> attribute d MaxBlockDimX <*> attribute d MaxBlockDimY <*> attribute d MaxBlockDimZ
  maxGridSize           <- (,,) <$> attribute d MaxGridDimX <*> attribute d MaxGridDimY <*> attribute d MaxGridDimZ

  -- The rest of the properties.
  --
  deviceName                    <- name d
  computeCapability             <- capability d
  totalGlobalMem                <- totalMem d
  multiProcessorCount           <- attribute d MultiprocessorCount
  computeMode                   <- toEnum <$> attribute d ComputeMode
  deviceOverlap                 <- toBool <$> attribute d GpuOverlap
  kernelExecTimeoutEnabled      <- toBool <$> attribute d KernelExecTimeout
  integrated                    <- toBool <$> attribute d Integrated
  canMapHostMemory              <- toBool <$> attribute d CanMapHostMemory
  concurrentKernels             <- toBool <$> attribute d ConcurrentKernels
  eccEnabled                    <- toBool <$> attribute d EccEnabled
  maxTextureDim1D               <- attribute d MaximumTexture1dWidth
  maxTextureDim2D               <- (,)  <$> attribute d MaximumTexture2dWidth <*> attribute d MaximumTexture2dHeight
  maxTextureDim3D               <- (,,) <$> attribute d MaximumTexture3dWidth <*> attribute d MaximumTexture3dHeight <*> attribute d MaximumTexture3dDepth
  asyncEngineCount              <- attribute d AsyncEngineCount
  cacheMemL2                    <- attribute d L2CacheSize
  maxThreadsPerMultiProcessor   <- attribute d MaxThreadsPerMultiprocessor
  memBusWidth                   <- attribute d GlobalMemoryBusWidth
  memClockRate                  <- attribute d MemoryClockRate
  pciInfo                       <- PCI <$> attribute d PciBusId <*> attribute d PciDeviceId <*> attribute d PciDomainId
  unifiedAddressing             <- toBool <$> attribute d UnifiedAddressing
  tccDriverEnabled              <- toBool <$> attribute d TccDriver
  streamPriorities              <- toBool <$> attribute d StreamPrioritiesSupported
  globalL1Cache                 <- toBool <$> attribute d GlobalL1CacheSupported
  localL1Cache                  <- toBool <$> attribute d LocalL1CacheSupported
  managedMemory                 <- toBool <$> attribute d ManagedMemory
  multiGPUBoard                 <- toBool <$> attribute d MultiGpuBoard
  multiGPUBoardGroupID          <- attribute d MultiGpuBoardGroupId
  preemption                    <- toBool <$> attribute d ComputePreemptionSupported
  singleToDoublePerfRatio       <- attribute d SingleToDoublePrecisionPerfRatio
  cooperativeLaunch             <- toBool <$> attribute d CooperativeLaunch
  cooperativeLaunchMultiDevice  <- toBool <$> attribute d CooperativeMultiDeviceLaunch

  return DeviceProperties{..}




-- |
-- 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 a2 =
  alloca $ \a1' ->
  let {a2' = useDevice a2} in
  totalMem'_ a1' a2' >>= \res ->
  checkStatus res >>
  peekIntConv  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 401 "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"
  device'_ :: ((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"
  count'_ :: ((C2HSImp.Ptr C2HSImp.CInt) -> (IO C2HSImp.CInt))

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

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

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