module Data.Array.Repa.Repr.ForeignPtr
( F, Array (..)
, fromForeignPtr, toForeignPtr
, computeIntoS, computeIntoP)
where
import Data.Array.Repa.Shape
import Data.Array.Repa.Base
import Data.Array.Repa.Eval.Load
import Data.Array.Repa.Eval.Target
import Data.Array.Repa.Repr.Delayed
import Foreign.Storable
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc
import System.IO.Unsafe
import qualified Foreign.ForeignPtr.Unsafe as Unsafe
data F
instance Storable a => Source F a where
data Array F sh a
= AForeignPtr !sh !Int !(ForeignPtr a)
linearIndex (AForeignPtr _ len fptr) ix
| ix < len
= unsafePerformIO
$ withForeignPtr fptr
$ \ptr -> peekElemOff ptr ix
| otherwise
= error "Repa: foreign array index out of bounds"
{-# INLINE linearIndex #-}
unsafeLinearIndex (AForeignPtr _ _ fptr) ix
= unsafePerformIO
$ withForeignPtr fptr
$ \ptr -> peekElemOff ptr ix
{-# INLINE unsafeLinearIndex #-}
extent (AForeignPtr sh _ _)
= sh
{-# INLINE extent #-}
deepSeqArray (AForeignPtr sh len fptr) x
= sh `deepSeq` len `seq` fptr `seq` x
{-# INLINE deepSeqArray #-}
instance Storable e => Target F e where
data MVec F e
= FPVec !Int !(ForeignPtr e)
newMVec n
= do let (proxy :: e) = undefined
ptr <- mallocBytes (sizeOf proxy * n)
_ <- peek ptr `asTypeOf` return proxy
fptr <- newForeignPtr finalizerFree ptr
return $ FPVec n fptr
{-# INLINE newMVec #-}
unsafeWriteMVec (FPVec _ fptr) !ix !x
= pokeElemOff (Unsafe.unsafeForeignPtrToPtr fptr) ix x
{-# INLINE unsafeWriteMVec #-}
unsafeFreezeMVec !sh (FPVec len fptr)
= return $ AForeignPtr sh len fptr
{-# INLINE unsafeFreezeMVec #-}
deepSeqMVec !(FPVec _ fptr) x
= Unsafe.unsafeForeignPtrToPtr fptr `seq` x
{-# INLINE deepSeqMVec #-}
touchMVec (FPVec _ fptr)
= touchForeignPtr fptr
{-# INLINE touchMVec #-}
fromForeignPtr
:: Shape sh
=> sh -> ForeignPtr e -> Array F sh e
fromForeignPtr !sh !fptr
= AForeignPtr sh (size sh) fptr
{-# INLINE fromForeignPtr #-}
toForeignPtr :: Array F sh e -> ForeignPtr e
toForeignPtr (AForeignPtr _ _ fptr)
= fptr
{-# INLINE toForeignPtr #-}
computeIntoS
:: (Load r1 sh e, Storable e)
=> ForeignPtr e -> Array r1 sh e -> IO ()
computeIntoS !fptr !arr
= loadS arr (FPVec 0 fptr)
{-# INLINE computeIntoS #-}
computeIntoP
:: (Load r1 sh e, Storable e)
=> ForeignPtr e -> Array r1 sh e -> IO ()
computeIntoP !fptr !arr
= loadP arr (FPVec 0 fptr)
{-# INLINE computeIntoP #-}