{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Data.Massiv.Array.Manifest.Vector (
fromVectorM,
fromVector',
castFromVector,
toVector,
castToVector,
ARepr,
VRepr,
) where
import Control.Monad (guard, join, msum)
import Data.Kind
import Data.Massiv.Array.Manifest.Boxed
import Data.Massiv.Array.Manifest.Internal
import Data.Massiv.Array.Manifest.Primitive
import Data.Massiv.Array.Manifest.Storable
import Data.Massiv.Array.Manifest.Unboxed
import Data.Massiv.Core.Common
import Data.Maybe (fromMaybe)
import Data.Typeable
import qualified Data.Vector as VB
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Primitive as VP
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Unboxed as VU
type family ARepr (v :: Type -> Type) :: Type where
ARepr VU.Vector = U
ARepr VS.Vector = S
ARepr VP.Vector = P
ARepr VB.Vector = BL
type family VRepr r :: Type -> Type where
VRepr U = VU.Vector
VRepr S = VS.Vector
VRepr P = VP.Vector
VRepr B = VB.Vector
VRepr BN = VB.Vector
VRepr BL = VB.Vector
castFromVector
:: forall v r ix e
. (VG.Vector v e, Typeable v, Index ix, ARepr v ~ r)
=> Comp
-> Sz ix
-> v e
-> Maybe (Array r ix e)
castFromVector :: forall (v :: * -> *) r ix e.
(Vector v e, Typeable v, Index ix, ARepr v ~ r) =>
Comp -> Sz ix -> v e -> Maybe (Array r ix e)
castFromVector Comp
comp Sz ix
sz v e
vector = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem Sz ix
sz Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== v e -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v e
vector)
[Maybe (Array r ix e)] -> Maybe (Array r ix e)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
[ do
Refl <- Maybe (v :~: Vector)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (v :~: VU.Vector)
uVector <- join $ gcast1 (Just vector)
return $ UArray{uComp = comp, uSize = sz, uData = uVector}
, do
Refl <- Maybe (v :~: Vector)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (v :~: VS.Vector)
sVector <- join $ gcast1 (Just vector)
return $ unsafeResize sz $ fromStorableVector comp sVector
, do
Refl <- Maybe (v :~: Vector)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (v :~: VP.Vector)
VP.Vector o _ ba <- join $ gcast1 (Just vector)
return $ PArray{pComp = comp, pSize = sz, pOffset = o, pData = ba}
, do
Refl <- Maybe (v :~: Vector)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (v :~: VB.Vector)
bVector <- join $ gcast1 (Just vector)
pure $ unsafeResize sz $ setComp comp $ fromBoxedVector bVector
]
{-# NOINLINE castFromVector #-}
fromVectorM
:: (MonadThrow m, Typeable v, VG.Vector v a, Manifest r a, Load (ARepr v) ix a, Load r ix a)
=> Comp
-> Sz ix
-> v a
-> m (Array r ix a)
fromVectorM :: forall (m :: * -> *) (v :: * -> *) a r ix.
(MonadThrow m, Typeable v, Vector v a, Manifest r a,
Load (ARepr v) ix a, Load r ix a) =>
Comp -> Sz ix -> v a -> m (Array r ix a)
fromVectorM Comp
comp Sz ix
sz v a
v =
case Comp -> Sz ix -> v a -> Maybe (Array (ARepr v) ix a)
forall (v :: * -> *) r ix e.
(Vector v e, Typeable v, Index ix, ARepr v ~ r) =>
Comp -> Sz ix -> v e -> Maybe (Array r ix e)
castFromVector Comp
comp Sz ix
sz v a
v of
Just Array (ARepr v) ix a
arr -> Array r ix a -> m (Array r ix a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array r ix a -> m (Array r ix a))
-> Array r ix a -> m (Array r ix a)
forall a b. (a -> b) -> a -> b
$ Array (ARepr v) ix a -> Array r ix a
forall r ix e r'.
(Manifest r e, Load r' ix e) =>
Array r' ix e -> Array r ix e
convert Array (ARepr v) ix a
arr
Maybe (Array (ARepr v) ix a)
Nothing -> do
Sz ix -> Sz Int -> m ()
forall (m :: * -> *) ix ix'.
(MonadThrow m, Index ix, Index ix') =>
Sz ix -> Sz ix' -> m ()
guardNumberOfElements Sz ix
sz (Int -> Sz Int
forall ix. Index ix => ix -> Sz ix
Sz (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
v))
Array r ix a -> m (Array r ix a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Comp -> Sz ix -> (Int -> a) -> Array r ix a
forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (Int -> e) -> Array r ix e
makeArrayLinear Comp
comp Sz ix
sz (v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
VG.unsafeIndex v a
v))
{-# NOINLINE fromVectorM #-}
fromVector'
:: (HasCallStack, Typeable v, VG.Vector v a, Load (ARepr v) ix a, Load r ix a, Manifest r a)
=> Comp
-> Sz ix
-> v a
-> Array r ix a
fromVector' :: forall (v :: * -> *) a ix r.
(HasCallStack, Typeable v, Vector v a, Load (ARepr v) ix a,
Load r ix a, Manifest r a) =>
Comp -> Sz ix -> v a -> Array r ix a
fromVector' Comp
comp Sz ix
sz = Either SomeException (Array r ix a) -> Array r ix a
forall a. HasCallStack => Either SomeException a -> a
throwEither (Either SomeException (Array r ix a) -> Array r ix a)
-> (v a -> Either SomeException (Array r ix a))
-> v a
-> Array r ix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Comp -> Sz ix -> v a -> Either SomeException (Array r ix a)
forall (m :: * -> *) (v :: * -> *) a r ix.
(MonadThrow m, Typeable v, Vector v a, Manifest r a,
Load (ARepr v) ix a, Load r ix a) =>
Comp -> Sz ix -> v a -> m (Array r ix a)
fromVectorM Comp
comp Sz ix
sz
{-# INLINE fromVector' #-}
castToVector
:: forall v r ix e
. (Manifest r e, Index ix, VRepr r ~ v)
=> Array r ix e
-> Maybe (v e)
castToVector :: forall (v :: * -> *) r ix e.
(Manifest r e, Index ix, VRepr r ~ v) =>
Array r ix e -> Maybe (v e)
castToVector Array r ix e
arr =
[Maybe (v e)] -> Maybe (v e)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
[ do
Refl <- Maybe (r :~: U)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: U)
uArr <- gcastArr arr
return $ uData uArr
, do
Refl <- Maybe (r :~: S)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: S)
sArr <- gcastArr arr
return $ toStorableVector sArr
, do
Refl <- Maybe (r :~: P)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: P)
pArr <- gcastArr arr
return $ VP.Vector (pOffset pArr) (totalElem (size arr)) $ pData pArr
, do
Refl <- Maybe (r :~: B)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: B)
bArr <- gcastArr arr
return $ toBoxedVector $ toLazyArray bArr
, do
Refl <- Maybe (r :~: BN)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: BN)
bArr <- gcastArr arr
return $ toBoxedVector $ toLazyArray $ unwrapNormalForm bArr
, do
Refl <- Maybe (r :~: BL)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT :: Maybe (r :~: BL)
bArr <- gcastArr arr
return $ toBoxedVector bArr
]
{-# NOINLINE castToVector #-}
toVector
:: forall r ix e v
. ( Manifest r e
, Load r ix e
, Manifest (ARepr v) e
, VG.Vector v e
, VRepr (ARepr v) ~ v
)
=> Array r ix e
-> v e
toVector :: forall r ix e (v :: * -> *).
(Manifest r e, Load r ix e, Manifest (ARepr v) e, Vector v e,
VRepr (ARepr v) ~ v) =>
Array r ix e -> v e
toVector Array r ix e
arr =
v e -> Maybe (v e) -> v e
forall a. a -> Maybe a -> a
fromMaybe
(Int -> (Int -> e) -> v e
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
VG.generate (Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem (Array r ix e -> Sz ix
forall r ix e. Size r => Array r ix e -> Sz ix
forall ix e. Array r ix e -> Sz ix
size Array r ix e
arr)) (Array r ix e -> Int -> e
forall ix. Index ix => Array r ix e -> Int -> e
forall r e ix. (Source r e, Index ix) => Array r ix e -> Int -> e
unsafeLinearIndex Array r ix e
arr))
(Array (ARepr v) ix e -> Maybe (v e)
forall (v :: * -> *) r ix e.
(Manifest r e, Index ix, VRepr r ~ v) =>
Array r ix e -> Maybe (v e)
castToVector (Array r ix e -> Array (ARepr v) ix e
forall r ix e r'.
(Manifest r e, Load r' ix e) =>
Array r' ix e -> Array r ix e
convert Array r ix e
arr :: Array (ARepr v) ix e))
{-# NOINLINE toVector #-}