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.Fill
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
data instance Array F sh e
= AForeignPtr !sh !Int !(ForeignPtr e)
instance Storable a => Repr F a where
linearIndex (AForeignPtr _ len fptr) ix
| ix < len
= unsafePerformIO
$ withForeignPtr fptr
$ \ptr -> peekElemOff ptr ix
| otherwise
= error "Repa: foreign array index out of bounds"
unsafeLinearIndex (AForeignPtr _ _ fptr) ix
= unsafePerformIO
$ withForeignPtr fptr
$ \ptr -> peekElemOff ptr ix
extent (AForeignPtr sh _ _)
= sh
deepSeqArray (AForeignPtr sh len fptr) x
= sh `deepSeq` len `seq` fptr `seq` x
instance Storable e => Fillable F e where
data MArr F e
= FPArr !Int !(ForeignPtr e)
newMArr n
= do let (proxy :: e) = undefined
ptr <- mallocBytes (sizeOf proxy * n)
_ <- peek ptr `asTypeOf` return proxy
fptr <- newForeignPtr finalizerFree ptr
return $ FPArr n fptr
unsafeWriteMArr (FPArr _ fptr) !ix !x
= pokeElemOff (Unsafe.unsafeForeignPtrToPtr fptr) ix x
unsafeFreezeMArr !sh (FPArr len fptr)
= return $ AForeignPtr sh len fptr
deepSeqMArr !(FPArr _ fptr) x
= Unsafe.unsafeForeignPtrToPtr fptr `seq` x
touchMArr (FPArr _ fptr)
= touchForeignPtr fptr
fromForeignPtr
:: Shape sh
=> sh -> ForeignPtr e -> Array F sh e
fromForeignPtr !sh !fptr
= AForeignPtr sh (size sh) fptr
toForeignPtr :: Array F sh e -> ForeignPtr e
toForeignPtr (AForeignPtr _ _ fptr)
= fptr
computeIntoS
:: Fill r1 F sh e
=> ForeignPtr e -> Array r1 sh e -> IO ()
computeIntoS !fptr !arr
= fillS arr (FPArr 0 fptr)
computeIntoP
:: Fill r1 F sh e
=> ForeignPtr e -> Array r1 sh e -> IO ()
computeIntoP !fptr !arr
= fillP arr (FPArr 0 fptr)