-- GENERATED by C->Haskell Compiler, version 0.17.2 Crystal Seed, 24 Jan 2009 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./Foreign/CUDA/Driver/Device.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Device
-- Copyright : (c) [2009..2012] Trevor L. McDonell
-- License   : BSD
--
-- Device management for low-level driver interface
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Device (

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

) where



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


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

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


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

newtype Device = Device { useDevice :: (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
                     | MaximumTexture2dLayeredHeight
                     | MaximumTexture2dLayeredLayers
                     | MaximumTexture2dArrayWidth
                     | MaximumTexture2dArrayHeight
                     | 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
                     | CU_DEVICE_ATTRIBUTE_MAX
                     deriving (Eq,Show)
instance Enum DeviceAttribute where
  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 MaximumTexture2dLayeredHeight = 28
  fromEnum MaximumTexture2dLayeredLayers = 29
  fromEnum MaximumTexture2dArrayWidth = 27
  fromEnum MaximumTexture2dArrayHeight = 28
  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 CU_DEVICE_ATTRIBUTE_MAX = 86

  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 = CU_DEVICE_ATTRIBUTE_MAX
  toEnum unmatched = error ("DeviceAttribute.toEnum: Cannot match " ++ show unmatched)

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



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



--
-- Properties of the compute device (internal helper)
--
data CUDevProp = CUDevProp
  {
    cuMaxThreadsPerBlock :: !Int,               -- Maximum number of threads per block
    cuMaxBlockSize       :: !(Int,Int,Int),     -- Maximum size of each dimension of a block
    cuMaxGridSize        :: !(Int,Int,Int),     -- Maximum size of each dimension of a grid
    cuSharedMemPerBlock  :: !Int64,             -- Shared memory available per block in bytes
    cuTotalConstMem      :: !Int64,             -- Constant memory available on device in bytes
    cuWarpSize           :: !Int,               -- Warp size in threads (SIMD width)
    cuMemPitch           :: !Int64,             -- Maximum pitch in bytes allowed by memory copies
    cuRegsPerBlock       :: !Int,               -- 32-bit registers available per block
    cuClockRate          :: !Int,               -- Clock frequency in kilohertz
    cuTextureAlignment   :: !Int64              -- Alignment requirement for textures
  }
  deriving (Show)


instance Storable CUDevProp where
  sizeOf _    = 56
{-# LINE 78 "./Foreign/CUDA/Driver/Device.chs" #-}

  alignment _ = alignment (undefined :: Ptr ())

  poke _ _    = error "no instance for Foreign.Storable.poke DeviceProperties"
  peek p      = do
    tb <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 0 ::IO CInt}) p
    sm <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 28 ::IO CInt}) p
    cm <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 32 ::IO CInt}) p
    ws <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 36 ::IO CInt}) p
    mp <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 40 ::IO CInt}) p
    rb <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 44 ::IO CInt}) p
    cl <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 48 ::IO CInt}) p
    ta <- cIntConv `fmap` (\ptr -> do {peekByteOff ptr 52 ::IO CInt}) p

    (t1:t2:t3:_) <- map cIntConv `fmap` peekArray 3 (p `plusPtr` devMaxThreadDimOffset' :: Ptr CInt)
    (g1:g2:g3:_) <- map cIntConv `fmap` peekArray 3 (p `plusPtr` devMaxGridSizeOffset'  :: Ptr CInt)

    return CUDevProp
      {
        cuMaxThreadsPerBlock = tb,
        cuMaxBlockSize       = (t1,t2,t3),
        cuMaxGridSize        = (g1,g2,g3),
        cuSharedMemPerBlock  = sm,
        cuTotalConstMem      = cm,
        cuWarpSize           = ws,
        cuMemPitch           = mp,
        cuRegsPerBlock       = rb,
        cuClockRate          = cl,
        cuTextureAlignment   = ta
      }


-- |
-- Possible option flags for CUDA initialisation. Dummy instance until the API
-- exports actual option values.
--
data InitFlag
instance Enum InitFlag where


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

-- |
-- Initialise the CUDA driver API. Must be called before any other driver
-- function.
--
{-# INLINEABLE initialise #-}
initialise :: [InitFlag] -> IO ()
initialise !flags = nothingIfOk =<< cuInit flags

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

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



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

-- |
-- Return the compute compatibility revision supported by the device
--
{-# INLINEABLE capability #-}
capability :: Device -> IO Compute
capability !dev =
  (\(!s,!a,!b) -> resultIfOk (s,Compute a b)) =<< cuDeviceComputeCapability dev

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

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



-- |
-- Return a device handle
--
{-# 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 164 "./Foreign/CUDA/Driver/Device.chs" #-}

  where dev = liftM Device . peek


-- |
-- Return the selected attribute for the given device
--
{-# 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 179 "./Foreign/CUDA/Driver/Device.chs" #-}



-- |
-- Return the number of device with compute capability > 1.0
--
{-# 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 191 "./Foreign/CUDA/Driver/Device.chs" #-}



-- |
-- Name of the device
--
{-# 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 204 "./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
--

-- Annoyingly, the driver API requires several different functions to extract
-- all device properties that are part of a single structure in the runtime API
--
{-# INLINEABLE props #-}
props :: Device -> IO DeviceProperties
props !d = do
  p   <- resultIfOk =<< cuDeviceGetProperties d

  -- And the remaining 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

  return DeviceProperties
    {
      deviceName                        = n,
      computeCapability                 = cc,
      totalGlobalMem                    = gm,
      totalConstMem                     = cuTotalConstMem p,
      sharedMemPerBlock                 = cuSharedMemPerBlock p,
      regsPerBlock                      = cuRegsPerBlock p,
      warpSize                          = cuWarpSize p,
      maxThreadsPerBlock                = cuMaxThreadsPerBlock p,
      maxBlockSize                      = cuMaxBlockSize p,
      maxGridSize                       = cuMaxGridSize p,
      clockRate                         = cuClockRate p,
      multiProcessorCount               = pc,
      memPitch                          = cuMemPitch p,
      textureAlignment                  = cuTextureAlignment p,
      computeMode                       = md,
      deviceOverlap                     = ov,
      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,
      kernelExecTimeoutEnabled          = ke,
      integrated                        = tg,
      canMapHostMemory                  = hm
    }


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

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



-- |
-- Total memory available on the device (bytes)
--
{-# 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 314 "./Foreign/CUDA/Driver/Device.chs" #-}



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

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

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

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

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

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

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

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