module Foreign.CUDA.Driver.Context.Base (
Context(..), ContextFlag(..),
create, destroy, device, pop, push, sync, get, set,
attach, detach,
) where
import Foreign.CUDA.Driver.Device ( Device(..) )
import Foreign.CUDA.Driver.Error
import Foreign.CUDA.Internal.C2HS
import Foreign
import Foreign.C
import Control.Monad ( liftM )
newtype Context = Context { useContext :: ((Ptr ()))}
deriving (Eq, Show)
data ContextFlag = SchedAuto
| SchedSpin
| SchedYield
| SchedBlockingSync
| BlockingSync
| SchedMask
| MapHost
| LmemResizeToMax
| FlagsMask
deriving (Eq,Show,Bounded)
instance Enum ContextFlag where
succ SchedAuto = SchedSpin
succ SchedSpin = SchedYield
succ SchedYield = SchedBlockingSync
succ SchedBlockingSync = SchedMask
succ BlockingSync = SchedMask
succ SchedMask = MapHost
succ MapHost = LmemResizeToMax
succ LmemResizeToMax = FlagsMask
succ FlagsMask = error "ContextFlag.succ: FlagsMask has no successor"
pred SchedSpin = SchedAuto
pred SchedYield = SchedSpin
pred SchedBlockingSync = SchedYield
pred BlockingSync = SchedYield
pred SchedMask = SchedBlockingSync
pred MapHost = SchedMask
pred LmemResizeToMax = MapHost
pred FlagsMask = LmemResizeToMax
pred SchedAuto = error "ContextFlag.pred: SchedAuto 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 FlagsMask
fromEnum SchedAuto = 0
fromEnum SchedSpin = 1
fromEnum SchedYield = 2
fromEnum SchedBlockingSync = 4
fromEnum BlockingSync = 4
fromEnum SchedMask = 7
fromEnum MapHost = 8
fromEnum LmemResizeToMax = 16
fromEnum FlagsMask = 31
toEnum 0 = SchedAuto
toEnum 1 = SchedSpin
toEnum 2 = SchedYield
toEnum 4 = SchedBlockingSync
toEnum 7 = SchedMask
toEnum 8 = MapHost
toEnum 16 = LmemResizeToMax
toEnum 31 = FlagsMask
toEnum unmatched = error ("ContextFlag.toEnum: Cannot match " ++ show unmatched)
create :: Device -> [ContextFlag] -> IO Context
create !dev !flags = resultIfOk =<< cuCtxCreate flags dev
cuCtxCreate :: ([ContextFlag]) -> (Device) -> IO ((Status), (Context))
cuCtxCreate a2 a3 =
alloca $ \a1' ->
let {a2' = combineBitMasks a2} in
let {a3' = useDevice a3} in
cuCtxCreate'_ a1' a2' a3' >>= \res ->
let {res' = cToEnum res} in
peekCtx a1'>>= \a1'' ->
return (res', a1'')
where peekCtx = liftM Context . peek
attach :: Context -> [ContextFlag] -> IO ()
attach !ctx !flags = nothingIfOk =<< cuCtxAttach ctx flags
cuCtxAttach :: (Context) -> ([ContextFlag]) -> IO ((Status))
cuCtxAttach a1 a2 =
withCtx a1 $ \a1' ->
let {a2' = combineBitMasks a2} in
cuCtxAttach'_ a1' a2' >>= \res ->
let {res' = cToEnum res} in
return (res')
where withCtx = with . useContext
detach :: Context -> IO ()
detach !ctx = nothingIfOk =<< cuCtxDetach ctx
cuCtxDetach :: (Context) -> IO ((Status))
cuCtxDetach a1 =
let {a1' = useContext a1} in
cuCtxDetach'_ a1' >>= \res ->
let {res' = cToEnum res} in
return (res')
destroy :: Context -> IO ()
destroy !ctx = nothingIfOk =<< cuCtxDestroy ctx
cuCtxDestroy :: (Context) -> IO ((Status))
cuCtxDestroy a1 =
let {a1' = useContext a1} in
cuCtxDestroy'_ a1' >>= \res ->
let {res' = cToEnum res} in
return (res')
get :: IO (Maybe Context)
get = resultIfOk =<< cuCtxGetCurrent
cuCtxGetCurrent :: IO ((Status), (Maybe Context))
cuCtxGetCurrent =
alloca $ \a1' ->
cuCtxGetCurrent'_ a1' >>= \res ->
let {res' = cToEnum res} in
peekCtx a1'>>= \a1'' ->
return (res', a1'')
where peekCtx = liftM (nothingIfNull Context) . peek
set :: Context -> IO ()
set !ctx = nothingIfOk =<< cuCtxSetCurrent ctx
cuCtxSetCurrent :: (Context) -> IO ((Status))
cuCtxSetCurrent a1 =
let {a1' = useContext a1} in
cuCtxSetCurrent'_ a1' >>= \res ->
let {res' = cToEnum res} in
return (res')
device :: IO Device
device = resultIfOk =<< cuCtxGetDevice
cuCtxGetDevice :: IO ((Status), (Device))
cuCtxGetDevice =
alloca $ \a1' ->
cuCtxGetDevice'_ a1' >>= \res ->
let {res' = cToEnum res} in
dev a1'>>= \a1'' ->
return (res', a1'')
where dev = liftM Device . peekIntConv
pop :: IO Context
pop = resultIfOk =<< cuCtxPopCurrent
cuCtxPopCurrent :: IO ((Status), (Context))
cuCtxPopCurrent =
alloca $ \a1' ->
cuCtxPopCurrent'_ a1' >>= \res ->
let {res' = cToEnum res} in
peekCtx a1'>>= \a1'' ->
return (res', a1'')
where peekCtx = liftM Context . peek
push :: Context -> IO ()
push !ctx = nothingIfOk =<< cuCtxPushCurrent ctx
cuCtxPushCurrent :: (Context) -> IO ((Status))
cuCtxPushCurrent a1 =
let {a1' = useContext a1} in
cuCtxPushCurrent'_ a1' >>= \res ->
let {res' = cToEnum res} in
return (res')
sync :: IO ()
sync = nothingIfOk =<< cuCtxSynchronize
cuCtxSynchronize :: IO ((Status))
cuCtxSynchronize =
cuCtxSynchronize'_ >>= \res ->
let {res' = cToEnum res} in
return (res')
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxCreate"
cuCtxCreate'_ :: ((Ptr (Ptr ())) -> (CUInt -> (CInt -> (IO CInt))))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxAttach"
cuCtxAttach'_ :: ((Ptr (Ptr ())) -> (CUInt -> (IO CInt)))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxDetach"
cuCtxDetach'_ :: ((Ptr ()) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxDestroy"
cuCtxDestroy'_ :: ((Ptr ()) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxGetCurrent"
cuCtxGetCurrent'_ :: ((Ptr (Ptr ())) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxSetCurrent"
cuCtxSetCurrent'_ :: ((Ptr ()) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxGetDevice"
cuCtxGetDevice'_ :: ((Ptr CInt) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxPopCurrent"
cuCtxPopCurrent'_ :: ((Ptr (Ptr ())) -> (IO CInt))
foreign import ccall unsafe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxPushCurrent"
cuCtxPushCurrent'_ :: ((Ptr ()) -> (IO CInt))
foreign import ccall safe "Foreign/CUDA/Driver/Context/Base.chs.h cuCtxSynchronize"
cuCtxSynchronize'_ :: (IO CInt)