{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_HADDOCK hide #-}
module Data.Array.Accelerate.Array.Unique
where
import Data.Array.Accelerate.Lifetime
import Control.Applicative
import Control.Concurrent.Unique
import Control.DeepSeq
import Foreign.ForeignPtr
import Foreign.ForeignPtr.Unsafe
import Foreign.Marshal.Array
import Foreign.Ptr
import Foreign.Storable
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Data.Word
import System.IO.Unsafe
import Prelude
data UniqueArray e = UniqueArray
{ uniqueArrayId :: {-# UNPACK #-} !Unique
, uniqueArrayData :: {-# UNPACK #-} !(Lifetime (ForeignPtr e))
}
instance NFData (UniqueArray e) where
rnf = rnfUniqueArray
{-# INLINE newUniqueArray #-}
newUniqueArray :: ForeignPtr e -> IO (UniqueArray e)
newUniqueArray fp = UniqueArray <$> newUnique <*> newLifetime fp
{-# INLINE withUniqueArrayPtr #-}
withUniqueArrayPtr :: UniqueArray a -> (Ptr a -> IO b) -> IO b
withUniqueArrayPtr ua go =
withLifetime (uniqueArrayData ua) $ \fp -> withForeignPtr fp go
{-# INLINE unsafeIndexArray #-}
unsafeIndexArray :: Storable e => UniqueArray e -> Int -> e
unsafeIndexArray !ua !i =
unsafePerformIO $! unsafeReadArray ua i
{-# INLINE unsafeReadArray #-}
unsafeReadArray :: Storable e => UniqueArray e -> Int -> IO e
unsafeReadArray !ua !i =
withUniqueArrayPtr ua $ \ptr -> peekElemOff ptr i
{-# INLINE unsafeWriteArray #-}
unsafeWriteArray :: Storable e => UniqueArray e -> Int -> e -> IO ()
unsafeWriteArray !ua !i !e =
withUniqueArrayPtr ua $ \ptr -> pokeElemOff ptr i e
{-# INLINE unsafeUniqueArrayPtr #-}
unsafeUniqueArrayPtr :: UniqueArray a -> Ptr a
unsafeUniqueArrayPtr = unsafeForeignPtrToPtr . unsafeGetValue . uniqueArrayData
{-# INLINE touchUniqueArray #-}
touchUniqueArray :: UniqueArray a -> IO ()
touchUniqueArray = touchLifetime . uniqueArrayData
rnfUniqueArray :: UniqueArray a -> ()
rnfUniqueArray (UniqueArray _ ad) = unsafeGetValue ad `seq` ()
liftUniqueArray :: forall a. Storable a => Int -> UniqueArray a -> Q (TExp (UniqueArray a))
liftUniqueArray sz ua = do
bytes <- runIO $ peekArray (sizeOf (undefined::a) * sz) (castPtr (unsafeUniqueArrayPtr ua) :: Ptr Word8)
[|| unsafePerformIO $ do
fp <- newForeignPtr_ $$( unsafeTExpCoerce [| Ptr $(litE (StringPrimL bytes)) |] )
ua' <- newUniqueArray (castForeignPtr fp)
return ua'
||]