numerical-0.0.0.0: src/Numerical/Array/Storage.hs
{-# LANGUAGE TypeFamilies,FlexibleInstances,MultiParamTypeClasses,FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances,StandaloneDeriving, DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveGeneric #-}
{-# LANGUAGE CPP #-}
module Numerical.Array.Storage(
Boxed
,Unboxed
,Stored
,BufferPure(..)
,BufferMut(..)
,Buffer
,MBuffer
,unsafeBufferThaw
,unsafeBufferFreeze) where
import Control.Monad.Primitive ( PrimMonad, PrimState )
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector as BV
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Unboxed as UV
--import qualified Data.Functor as F hiding (Functor)
--import qualified Data.Foldable as F hiding (Foldable)
--import qualified Data.Traversable as T hiding (Traversable)
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 709
--import Data.Functor (Functor)
import Data.Foldable (Foldable)
import Data.Traversable (Traversable)
#endif
import Data.Typeable
import Data.Data
import GHC.Generics
{-
FIXME : should i require that the element type and
mode are both instance of Typeable for Buffers?
-}
{-
FIX MEEEEE REMINDERS
make the allocators for Storable Buffers do AVX sized alignment
-}
-- | The class instance @'Buffer' mode a@ is a shorthand for saying that a given buffer representation @mode@
-- has a 'VG.Vector' instance for both 'BufferPure' and 'BufferMut'.
class (VG.Vector (BufferPure mode) a, VGM.MVector (BufferMut mode) a)=> Buffer mode a
instance (VG.Vector (BufferPure mode) a, VGM.MVector (BufferMut mode) a)=> Buffer mode a
-- not sure if MBuffer class should exist, fixme. if/when removed, this
class VGM.MVector (BufferMut mode) a=> MBuffer mode a
-- not sure if MBuffer should exist, FIXME
instance VGM.MVector (BufferMut mode) a=> MBuffer mode a
-- | 'Boxed' is the type index for `Buffer`s that use the boxed data structure `Data.Vector.Vector`
-- as the underlying storage representation.
data Boxed
deriving Typeable
deriving instance Data Boxed
-- | 'Unboxed' is the type index for 'Buffer's that use the unboxed data structure
-- 'Data.Vector.Unboxed.Vector' as the underlying storage representation.
data Unboxed
deriving Typeable
deriving instance Data Unboxed
-- | 'Stored' is the type index for 'Buffer's that use the 'Foreign.Storable'
-- for values, in pinned byte array buffers, provided by 'Data.Vector.Storable'
data Stored
deriving Typeable
deriving instance Data Stored
type instance VG.Mutable (BufferPure sort) = BufferMut sort
data family BufferPure sort elem
deriving instance Typeable BufferPure
newtype instance BufferPure Boxed elem = BoxedBuffer (BV.Vector elem)
deriving (Show,Data,Generic,Functor,Foldable,Traversable)
newtype instance BufferPure Unboxed elem = UnboxedBuffer (UV.Vector elem)
deriving (Show,Data,Generic)
--deriving instance Typeable a => Typeable (BufferPure Unboxed a)
newtype instance BufferPure Stored elem = StorableBuffer (SV.Vector elem)
deriving (Show,Data,Generic)
data family BufferMut sort st elem
deriving instance Typeable BufferMut
newtype instance BufferMut Boxed st elem = BoxedBufferMut (BV.MVector st elem)
--deriving (Show,Data,Generic)
newtype instance BufferMut Unboxed st elem = UnboxedBufferMut (UV.MVector st elem)
--deriving (Show,Data,Generic)
newtype instance BufferMut Stored st elem = StorableBufferMut (SV.MVector st elem)
-- | 'unsafeBufferFreeze'
unsafeBufferFreeze :: (Buffer rep a,PrimMonad m) => BufferMut rep (PrimState m ) a -> m (BufferPure rep a)
unsafeBufferFreeze = VG.basicUnsafeFreeze
unsafeBufferThaw :: (Buffer rep a,PrimMonad m) => (BufferPure rep a) -> m (BufferMut rep (PrimState m ) a)
unsafeBufferThaw = VG.basicUnsafeThaw
instance (VGM.MVector BV.MVector elem) => VGM.MVector (BufferMut Boxed) elem where
basicInitialize = \(BoxedBufferMut v) -> VGM.basicInitialize v
basicLength = \(BoxedBufferMut v) -> VGM.basicLength v
basicUnsafeSlice =
\ ix1 ix2 (BoxedBufferMut bv) ->
BoxedBufferMut $ VGM.basicUnsafeSlice ix1 ix2 bv
basicOverlaps =
\ (BoxedBufferMut bv1) (BoxedBufferMut bv2) -> VGM.basicOverlaps bv1 bv2
basicUnsafeNew = \ size ->
do
res<- VGM.basicUnsafeNew size
return (BoxedBufferMut res)
basicUnsafeRead= \(BoxedBufferMut bv) ix -> VGM.basicUnsafeRead bv ix
basicUnsafeWrite = \(BoxedBufferMut bv ) ix val -> VGM.basicUnsafeWrite bv ix val
{-Q/todo/check fixme, do these other operations need be provided in a pass through way too?
or will there be no difference in the derived code perf ? -}
-- basicUnsafeClear
-- basicUnsafeSet
-- basicUnsafeCopy
-- basicUnsafeMove
-- basicUnsafeGrow
-- basicUnsafeReplicate
{-# INLINE basicInitialize #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicOverlaps #-}
{-# INLINE basicUnsafeNew #-}
{-# INLINE basicUnsafeRead #-}
{-# INLINE basicUnsafeWrite #-}
-- {-# INLINE basicUnsafeClear#-}
-- {-# INLINE basicUnsafeSet#-}
-- {-# INLINE basicUnsafeCopy#-}
-- {-# INLINE basicUnsafeMove#-}
-- {-# INLINE basicUnsafeGrow#-}
-- {-# INLINE basicUnsafeReplicate#-}
instance (SV.Storable elem) => VGM.MVector (BufferMut Stored) elem where
basicInitialize = \(StorableBufferMut v) -> VGM.basicInitialize v
basicLength = \(StorableBufferMut v) -> VGM.basicLength v
basicUnsafeSlice =
\ ix1 ix2 (StorableBufferMut bv) ->
StorableBufferMut $ VGM.basicUnsafeSlice ix1 ix2 bv
basicOverlaps =
\ (StorableBufferMut bv1) (StorableBufferMut bv2) -> VGM.basicOverlaps bv1 bv2
basicUnsafeNew = \ size ->
do
res<- VGM.basicUnsafeNew size
return (StorableBufferMut res)
basicUnsafeRead= \(StorableBufferMut bv) ix -> VGM.basicUnsafeRead bv ix
basicUnsafeWrite = \(StorableBufferMut bv ) ix val -> VGM.basicUnsafeWrite bv ix val
{-# INLINE basicInitialize #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicOverlaps #-}
{-# INLINE basicUnsafeNew #-}
{-# INLINE basicUnsafeRead #-}
{-# INLINE basicUnsafeWrite #-}
instance (VGM.MVector UV.MVector elem) => VGM.MVector (BufferMut Unboxed) elem where
{-# INLINE basicInitialize #-}
basicInitialize = \(UnboxedBufferMut v) -> VGM.basicInitialize v
basicLength = \(UnboxedBufferMut v) -> VGM.basicLength v
basicUnsafeSlice =
\ ix1 ix2 (UnboxedBufferMut bv) ->
UnboxedBufferMut $ VGM.basicUnsafeSlice ix1 ix2 bv
basicOverlaps =
\ (UnboxedBufferMut bv1) (UnboxedBufferMut bv2) -> VGM.basicOverlaps bv1 bv2
basicUnsafeNew = \ size ->
do
res<- VGM.basicUnsafeNew size
return (UnboxedBufferMut res)
basicUnsafeRead= \(UnboxedBufferMut bv) ix -> VGM.basicUnsafeRead bv ix
basicUnsafeWrite = \(UnboxedBufferMut bv ) ix val -> VGM.basicUnsafeWrite bv ix val
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicOverlaps #-}
{-# INLINE basicUnsafeNew #-}
{-# INLINE basicUnsafeRead #-}
{-# INLINE basicUnsafeWrite #-}
----
----
instance VG.Vector BV.Vector a => VG.Vector (BufferPure Boxed) a where
basicUnsafeFreeze =
\(BoxedBufferMut mv) ->(\ x->return $ BoxedBuffer x) =<< VG.basicUnsafeFreeze mv
basicUnsafeThaw= \(BoxedBuffer v) ->(\x -> return $ BoxedBufferMut x ) =<< VG.basicUnsafeThaw v
basicLength = \(BoxedBuffer v) -> VG.basicLength v
basicUnsafeSlice =
\ start len (BoxedBuffer v) -> BoxedBuffer $! VG.basicUnsafeSlice start len v
basicUnsafeIndexM =
\ (BoxedBuffer v) ix -> VG.basicUnsafeIndexM v ix
elemseq = \ (BoxedBuffer v) a b -> VG.elemseq v a b
{-# INLINE basicUnsafeFreeze #-}
{-# INLINE basicUnsafeThaw #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicUnsafeIndexM #-}
{-# INLINE elemseq #-}
instance (SV.Storable a) => VG.Vector (BufferPure Stored) a where
basicUnsafeFreeze =
\(StorableBufferMut mv) -> (\x ->return $StorableBuffer x) =<< VG.basicUnsafeFreeze mv
basicUnsafeThaw=
\(StorableBuffer v) -> (\x -> return $ StorableBufferMut x) =<< VG.basicUnsafeThaw v
basicLength = \(StorableBuffer v) -> VG.basicLength v
basicUnsafeSlice =
\ start len (StorableBuffer v) -> StorableBuffer $! VG.basicUnsafeSlice start len v
basicUnsafeIndexM =
\ (StorableBuffer v) ix -> VG.basicUnsafeIndexM v ix
elemseq = \ (StorableBuffer v) a b -> VG.elemseq v a b
{-# INLINE basicUnsafeFreeze #-}
{-# INLINE basicUnsafeThaw #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicUnsafeIndexM #-}
{-# INLINE elemseq #-}
instance VG.Vector UV.Vector a => VG.Vector (BufferPure Unboxed) a where
basicUnsafeFreeze = \(UnboxedBufferMut mv) -> (\x -> return $ UnboxedBuffer x) =<< VG.basicUnsafeFreeze mv
basicUnsafeThaw= \(UnboxedBuffer v) ->(\x -> return $ UnboxedBufferMut x) =<< VG.basicUnsafeThaw v
basicLength = \(UnboxedBuffer v) -> VG.basicLength v
basicUnsafeSlice =
\ start len (UnboxedBuffer v) -> UnboxedBuffer $! VG.basicUnsafeSlice start len v
basicUnsafeIndexM =
\ (UnboxedBuffer v) ix -> VG.basicUnsafeIndexM v ix
elemseq = \ (UnboxedBuffer v) a b -> VG.elemseq v a b
{-# INLINE basicUnsafeFreeze #-}
{-# INLINE basicUnsafeThaw #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicUnsafeIndexM #-}
{-# INLINE elemseq #-}