{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
-- Module      : Data.Massiv.Array.Manifest.Boxed
-- Copyright   : (c) Alexey Kuleshevich 2018-2020
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability   : experimental
-- Portability : non-portable
--
module Data.Massiv.Array.Manifest.Boxed
  ( B(..)
  , N(..)
  , Array(..)
  , unwrapNormalForm
  , evalNormalForm
  , unwrapArray
  , evalArray
  , unwrapMutableArray
  , evalMutableArray
  , unwrapNormalFormArray
  , evalNormalFormArray
  , unwrapNormalFormMutableArray
  , evalNormalFormMutableArray
  , toBoxedVector
  , toBoxedMVector
  , evalBoxedVector
  , evalBoxedMVector
  , evalNormalBoxedVector
  , evalNormalBoxedMVector
  , unsafeBoxedArray
  , unsafeNormalBoxedArray
  , unsafeFromBoxedVector
  , seqArray
  , deepseqArray
  ) where

import Control.DeepSeq (NFData(..), deepseq)
import Control.Exception
import Control.Monad ((>=>))
import Control.Monad.Primitive
import Control.Monad.ST (runST)
import qualified Data.Foldable as F (Foldable(..))
import Data.Massiv.Array.Delayed.Push (DL)
import Data.Massiv.Array.Delayed.Stream (DS)
import Data.Massiv.Array.Manifest.Internal (M, computeAs, toManifest)
import Data.Massiv.Array.Manifest.List as L
import Data.Massiv.Vector.Stream as S (steps, isteps)
import Data.Massiv.Array.Mutable
import Data.Massiv.Array.Ops.Fold
import Data.Massiv.Array.Ops.Fold.Internal
import Data.Massiv.Array.Ops.Map (traverseA)
import Data.Massiv.Core.Common
import Data.Massiv.Core.List
import qualified Data.Primitive.Array as A
import qualified Data.Vector as VB
import qualified Data.Vector.Mutable as MVB
import GHC.Exts as GHC
import Prelude hiding (mapM)
import System.IO.Unsafe (unsafePerformIO)

#include "massiv.h"

sizeofArray :: A.Array e -> Int
sizeofMutableArray :: A.MutableArray s e -> Int
#if MIN_VERSION_primitive(0,6,2)
sizeofArray :: Array e -> Int
sizeofArray = Array e -> Int
forall a. Array a -> Int
A.sizeofArray
sizeofMutableArray :: MutableArray s e -> Int
sizeofMutableArray = MutableArray s e -> Int
forall s a. MutableArray s a -> Int
A.sizeofMutableArray
#else
sizeofArray (A.Array a#) = I# (sizeofArray# a#)
sizeofMutableArray (A.MutableArray ma#) = I# (sizeofMutableArray# ma#)
#endif

------------------
-- Boxed Strict --
------------------

-- | Array representation for Boxed elements. This structure is element and
-- spine strict, but elements are strict to Weak Head Normal Form (WHNF) only.
data B = B deriving Int -> B -> ShowS
[B] -> ShowS
B -> String
(Int -> B -> ShowS) -> (B -> String) -> ([B] -> ShowS) -> Show B
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [B] -> ShowS
$cshowList :: [B] -> ShowS
show :: B -> String
$cshow :: B -> String
showsPrec :: Int -> B -> ShowS
$cshowsPrec :: Int -> B -> ShowS
Show

data instance Array B ix e = BArray { Array B ix e -> Comp
bComp   :: !Comp
                                    , Array B ix e -> Sz ix
bSize   :: !(Sz ix)
                                    , Array B ix e -> Int
bOffset :: {-# UNPACK #-} !Int
                                    , Array B ix e -> Array e
bData   :: {-# UNPACK #-} !(A.Array e)
                                    }

instance (Ragged L ix e, Show e) => Show (Array B ix e) where
  showsPrec :: Int -> Array B ix e -> ShowS
showsPrec = (Array B ix e -> Array B ix e) -> Int -> Array B ix e -> ShowS
forall r r' ix ix' e.
(Ragged L ix' e, Load r ix e, Source r' ix' e, Show e) =>
(Array r ix e -> Array r' ix' e) -> Int -> Array r ix e -> ShowS
showsArrayPrec Array B ix e -> Array B ix e
forall a. a -> a
id
  showList :: [Array B ix e] -> ShowS
showList = [Array B ix e] -> ShowS
forall arr. Show arr => [arr] -> ShowS
showArrayList

instance (Ragged L ix e, Show e) => Show (Array DL ix e) where
  showsPrec :: Int -> Array DL ix e -> ShowS
showsPrec = (Array DL ix e -> Array B ix e) -> Int -> Array DL ix e -> ShowS
forall r r' ix ix' e.
(Ragged L ix' e, Load r ix e, Source r' ix' e, Show e) =>
(Array r ix e -> Array r' ix' e) -> Int -> Array r ix e -> ShowS
showsArrayPrec (B -> Array DL ix e -> Array B ix e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B)
  showList :: [Array DL ix e] -> ShowS
showList = [Array DL ix e] -> ShowS
forall arr. Show arr => [arr] -> ShowS
showArrayList

instance Show e => Show (Array DS Ix1 e) where
  showsPrec :: Int -> Array DS Int e -> ShowS
showsPrec = (Array DS Int e -> Array B Int e) -> Int -> Array DS Int e -> ShowS
forall r r' ix ix' e.
(Ragged L ix' e, Load r ix e, Source r' ix' e, Show e) =>
(Array r ix e -> Array r' ix' e) -> Int -> Array r ix e -> ShowS
showsArrayPrec (B -> Array DS Int e -> Array B Int e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B)
  showList :: [Array DS Int e] -> ShowS
showList = [Array DS Int e] -> ShowS
forall arr. Show arr => [arr] -> ShowS
showArrayList


instance (Index ix, NFData e) => NFData (Array B ix e) where
  rnf :: Array B ix e -> ()
rnf = (Array B ix e -> () -> ()
forall a ix t. (NFData a, Index ix) => Array B ix a -> t -> t
`deepseqArray` ())
  {-# INLINE rnf #-}

instance (Index ix, Eq e) => Eq (Array B ix e) where
  == :: Array B ix e -> Array B ix e -> Bool
(==) = (e -> e -> Bool) -> Array B ix e -> Array B ix e -> Bool
forall r1 ix e1 r2 e2.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> Bool) -> Array r1 ix e1 -> Array r2 ix e2 -> Bool
eqArrays e -> e -> Bool
forall a. Eq a => a -> a -> Bool
(==)
  {-# INLINE (==) #-}

instance (Index ix, Ord e) => Ord (Array B ix e) where
  compare :: Array B ix e -> Array B ix e -> Ordering
compare = (e -> e -> Ordering) -> Array B ix e -> Array B ix e -> Ordering
forall r1 ix e1 r2 e2.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> Ordering)
-> Array r1 ix e1 -> Array r2 ix e2 -> Ordering
compareArrays e -> e -> Ordering
forall a. Ord a => a -> a -> Ordering
compare
  {-# INLINE compare #-}

instance Index ix => Construct B ix e where
  setComp :: Comp -> Array B ix e -> Array B ix e
setComp Comp
c Array B ix e
arr = Array B ix e
R:ArrayBixe ix e
arr { bComp :: Comp
bComp = Comp
c }
  {-# INLINE setComp #-}

  makeArrayLinear :: Comp -> Sz ix -> (Int -> e) -> Array B ix e
makeArrayLinear !Comp
comp !Sz ix
sz Int -> e
f = IO (Array B ix e) -> Array B ix e
forall a. IO a -> a
unsafePerformIO (IO (Array B ix e) -> Array B ix e)
-> IO (Array B ix e) -> Array B ix e
forall a b. (a -> b) -> a -> b
$ Comp -> Sz ix -> (Int -> IO e) -> IO (Array B ix e)
forall r ix e (m :: * -> *).
(MonadUnliftIO m, PrimMonad m, Mutable r ix e) =>
Comp -> Sz ix -> (Int -> m e) -> m (Array r ix e)
generateArrayLinear Comp
comp Sz ix
sz (\ !Int
i -> e -> IO e
forall (m :: * -> *) a. Monad m => a -> m a
return (e -> IO e) -> e -> IO e
forall a b. (a -> b) -> a -> b
$! Int -> e
f Int
i)
  {-# INLINE makeArrayLinear #-}

instance Index ix => Source B ix e where
  unsafeLinearIndex :: Array B ix e -> Int -> e
unsafeLinearIndex (BArray _ _sz o a) Int
i =
    INDEX_CHECK("(Source B ix e).unsafeLinearIndex",
                SafeSz . sizeofArray, A.indexArray) a (i + o)
  {-# INLINE unsafeLinearIndex #-}

  unsafeLinearSlice :: Int -> Sz1 -> Array B ix e -> Array B Int e
unsafeLinearSlice Int
i Sz1
k (BArray c _ o a) = Comp -> Sz1 -> Int -> Array e -> Array B Int e
forall ix e. Comp -> Sz ix -> Int -> Array e -> Array B ix e
BArray Comp
c Sz1
k (Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) Array e
a
  {-# INLINE unsafeLinearSlice #-}


instance Index ix => Resize B ix where
  unsafeResize :: Sz ix' -> Array B ix e -> Array B ix' e
unsafeResize !Sz ix'
sz !Array B ix e
arr = Array B ix e
R:ArrayBixe ix e
arr { bSize :: Sz ix'
bSize = Sz ix'
sz }
  {-# INLINE unsafeResize #-}

instance Index ix => Extract B ix e where
  unsafeExtract :: ix -> Sz ix -> Array B ix e -> Array (R B) ix e
unsafeExtract !ix
sIx !Sz ix
newSz !Array B ix e
arr = ix -> Sz ix -> Array M ix e -> Array (R M) ix e
forall r ix e.
Extract r ix e =>
ix -> Sz ix -> Array r ix e -> Array (R r) ix e
unsafeExtract ix
sIx Sz ix
newSz (Array B ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest Array B ix e
arr)
  {-# INLINE unsafeExtract #-}


instance ( Index ix
         , Index (Lower ix)
         , Elt M ix e ~ Array M (Lower ix) e
         , Elt B ix e ~ Array M (Lower ix) e
         ) =>
         OuterSlice B ix e where
  unsafeOuterSlice :: Array B ix e -> Int -> Elt B ix e
unsafeOuterSlice Array B ix e
arr = Array M ix e -> Int -> Elt M ix e
forall r ix e.
OuterSlice r ix e =>
Array r ix e -> Int -> Elt r ix e
unsafeOuterSlice (Array B ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest Array B ix e
arr)
  {-# INLINE unsafeOuterSlice #-}

instance ( Index ix
         , Index (Lower ix)
         , Elt M ix e ~ Array M (Lower ix) e
         , Elt B ix e ~ Array M (Lower ix) e
         ) =>
         InnerSlice B ix e where
  unsafeInnerSlice :: Array B ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt B ix e
unsafeInnerSlice Array B ix e
arr = Array M ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt M ix e
forall r ix e.
InnerSlice r ix e =>
Array r ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt r ix e
unsafeInnerSlice (Array B ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest Array B ix e
arr)
  {-# INLINE unsafeInnerSlice #-}

instance {-# OVERLAPPING #-} Slice B Ix1 e where
  unsafeSlice :: Array B Int e -> Int -> Sz1 -> Dim -> m (Elt B Int e)
unsafeSlice Array B Int e
arr Int
i Sz1
_ Dim
_ = e -> m e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array B Int e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array B Int e
arr Int
i)
  {-# INLINE unsafeSlice #-}


instance Index ix => Manifest B ix e where

  unsafeLinearIndexM :: Array B ix e -> Int -> e
unsafeLinearIndexM (BArray _ _sz o a) Int
i =
    INDEX_CHECK("(Manifest B ix e).unsafeLinearIndexM",
                SafeSz . sizeofArray, A.indexArray) a (i + o)
  {-# INLINE unsafeLinearIndexM #-}


instance Index ix => Mutable B ix e where
  data MArray s B ix e = MBArray !(Sz ix) {-# UNPACK #-} !Int {-# UNPACK #-} !(A.MutableArray s e)

  msize :: MArray s B ix e -> Sz ix
msize (MBArray sz _ _) = Sz ix
sz
  {-# INLINE msize #-}

  unsafeThaw :: Array B ix e -> m (MArray (PrimState m) B ix e)
unsafeThaw (BArray _ sz o a) = Sz ix
-> Int
-> MutableArray (PrimState m) e
-> MArray (PrimState m) B ix e
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray Sz ix
sz Int
o (MutableArray (PrimState m) e -> MArray (PrimState m) B ix e)
-> m (MutableArray (PrimState m) e)
-> m (MArray (PrimState m) B ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array e -> m (MutableArray (PrimState m) e)
forall (m :: * -> *) a.
PrimMonad m =>
Array a -> m (MutableArray (PrimState m) a)
A.unsafeThawArray Array e
a
  {-# INLINE unsafeThaw #-}

  unsafeFreeze :: Comp -> MArray (PrimState m) B ix e -> m (Array B ix e)
unsafeFreeze Comp
comp (MBArray sz o ma) = Comp -> Sz ix -> Int -> Array e -> Array B ix e
forall ix e. Comp -> Sz ix -> Int -> Array e -> Array B ix e
BArray Comp
comp Sz ix
sz Int
o (Array e -> Array B ix e) -> m (Array e) -> m (Array B ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableArray (PrimState m) e -> m (Array e)
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> m (Array a)
A.unsafeFreezeArray MutableArray (PrimState m) e
ma
  {-# INLINE unsafeFreeze #-}

  unsafeNew :: Sz ix -> m (MArray (PrimState m) B ix e)
unsafeNew Sz ix
sz = Sz ix
-> Int
-> MutableArray (PrimState m) e
-> MArray (PrimState m) B ix e
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray Sz ix
sz Int
0 (MutableArray (PrimState m) e -> MArray (PrimState m) B ix e)
-> m (MutableArray (PrimState m) e)
-> m (MArray (PrimState m) B ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> e -> m (MutableArray (PrimState m) e)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
A.newArray (Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem Sz ix
sz) e
forall a. a
uninitialized
  {-# INLINE unsafeNew #-}

  initialize :: MArray (PrimState m) B ix e -> m ()
initialize MArray (PrimState m) B ix e
_ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  {-# INLINE initialize #-}

  unsafeLinearRead :: MArray (PrimState m) B ix e -> Int -> m e
unsafeLinearRead (MBArray _ o ma) Int
i =
    INDEX_CHECK("(Mutable B ix e).unsafeLinearRead",
                SafeSz . sizeofMutableArray, A.readArray) ma (i + o)
  {-# INLINE unsafeLinearRead #-}

  unsafeLinearWrite :: MArray (PrimState m) B ix e -> Int -> e -> m ()
unsafeLinearWrite (MBArray _sz o ma) Int
i e
e = e
e e -> m () -> m ()
`seq`
    INDEX_CHECK("(Mutable B ix e).unsafeLinearWrite",
                SafeSz . sizeofMutableArray, A.writeArray) ma (i + o) e
  {-# INLINE unsafeLinearWrite #-}

instance Index ix => Load B ix e where
  type R B = M
  size :: Array B ix e -> Sz ix
size = Array B ix e -> Sz ix
forall ix e. Array B ix e -> Sz ix
bSize
  {-# INLINE size #-}
  getComp :: Array B ix e -> Comp
getComp = Array B ix e -> Comp
forall ix e. Array B ix e -> Comp
bComp
  {-# INLINE getComp #-}
  loadArrayM :: Scheduler m () -> Array B ix e -> (Int -> e -> m ()) -> m ()
loadArrayM !Scheduler m ()
scheduler !Array B ix e
arr = Scheduler m () -> Int -> (Int -> e) -> (Int -> e -> m ()) -> m ()
forall (m :: * -> *) b.
Monad m =>
Scheduler m () -> Int -> (Int -> b) -> (Int -> b -> m ()) -> m ()
splitLinearlyWith_ Scheduler m ()
scheduler (Array B ix e -> Int
forall r ix e. Load r ix e => Array r ix e -> Int
elemsCount Array B ix e
arr) (Array B ix e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array B ix e
arr)
  {-# INLINE loadArrayM #-}

instance Index ix => StrideLoad B ix e

instance Index ix => Stream B ix e where
  toStream :: Array B ix e -> Steps Id e
toStream = Array B ix e -> Steps Id e
forall r ix e (m :: * -> *).
(Monad m, Source r ix e) =>
Array r ix e -> Steps m e
S.steps
  {-# INLINE toStream #-}
  toStreamIx :: Array B ix e -> Steps Id (ix, e)
toStreamIx = Array B ix e -> Steps Id (ix, e)
forall r ix e (m :: * -> *).
(Monad m, Source r ix e) =>
Array r ix e -> Steps m (ix, e)
S.isteps
  {-# INLINE toStreamIx #-}


-- | Row-major sequential folding over a Boxed array.
instance Index ix => Foldable (Array B ix) where
  fold :: Array B ix m -> m
fold = Array B ix m -> m
forall e r ix. (Monoid e, Source r ix e) => Array r ix e -> e
fold
  {-# INLINE fold #-}
  foldMap :: (a -> m) -> Array B ix a -> m
foldMap = (a -> m) -> Array B ix a -> m
forall r ix e m.
(Source r ix e, Monoid m) =>
(e -> m) -> Array r ix e -> m
foldMono
  {-# INLINE foldMap #-}
  foldl :: (b -> a -> b) -> b -> Array B ix a -> b
foldl = (b -> a -> b) -> b -> Array B ix a -> b
forall r ix e a.
Source r ix e =>
(a -> e -> a) -> a -> Array r ix e -> a
lazyFoldlS
  {-# INLINE foldl #-}
  foldl' :: (b -> a -> b) -> b -> Array B ix a -> b
foldl' = (b -> a -> b) -> b -> Array B ix a -> b
forall r ix e a.
Source r ix e =>
(a -> e -> a) -> a -> Array r ix e -> a
foldlS
  {-# INLINE foldl' #-}
  foldr :: (a -> b -> b) -> b -> Array B ix a -> b
foldr = (a -> b -> b) -> b -> Array B ix a -> b
forall r ix e b.
Source r ix e =>
(e -> b -> b) -> b -> Array r ix e -> b
foldrFB
  {-# INLINE foldr #-}
  foldr' :: (a -> b -> b) -> b -> Array B ix a -> b
foldr' = (a -> b -> b) -> b -> Array B ix a -> b
forall r ix e b.
Source r ix e =>
(e -> b -> b) -> b -> Array r ix e -> b
foldrS
  {-# INLINE foldr' #-}
  null :: Array B ix a -> Bool
null (BArray _ sz _ _) = Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem Sz ix
sz Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
  {-# INLINE null #-}
  length :: Array B ix a -> Int
length = Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem (Sz ix -> Int) -> (Array B ix a -> Sz ix) -> Array B ix a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array B ix a -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size
  {-# INLINE length #-}
  toList :: Array B ix a -> [a]
toList Array B ix a
arr = (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build (\ a -> b -> b
c b
n -> (a -> b -> b) -> b -> Array B ix a -> b
forall r ix e b.
Source r ix e =>
(e -> b -> b) -> b -> Array r ix e -> b
foldrFB a -> b -> b
c b
n Array B ix a
arr)
  {-# INLINE toList #-}


instance Index ix => Functor (Array B ix) where
  fmap :: (a -> b) -> Array B ix a -> Array B ix b
fmap a -> b
f Array B ix a
arr = Comp -> Sz ix -> (Int -> b) -> Array B ix b
forall r ix e.
Construct r ix e =>
Comp -> Sz ix -> (Int -> e) -> Array r ix e
makeArrayLinear (Array B ix a -> Comp
forall ix e. Array B ix e -> Comp
bComp Array B ix a
arr) (Array B ix a -> Sz ix
forall ix e. Array B ix e -> Sz ix
bSize Array B ix a
arr) (a -> b
f (a -> b) -> (Int -> a) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array B ix a -> Int -> a
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array B ix a
arr)
  {-# INLINE fmap #-}

instance Index ix => Traversable (Array B ix) where
  traverse :: (a -> f b) -> Array B ix a -> f (Array B ix b)
traverse = (a -> f b) -> Array B ix a -> f (Array B ix b)
forall r ix e r' a (f :: * -> *).
(Source r' ix a, Mutable r ix e, Applicative f) =>
(a -> f e) -> Array r' ix a -> f (Array r ix e)
traverseA
  {-# INLINE traverse #-}

instance ( IsList (Array L ix e)
         , Nested LN ix e
         , Nested L ix e
         , Ragged L ix e
         ) =>
         IsList (Array B ix e) where
  type Item (Array B ix e) = Item (Array L ix e)
  fromList :: [Item (Array B ix e)] -> Array B ix e
fromList = Comp -> [ListItem ix e] -> Array B ix e
forall r ix e.
(Nested LN ix e, Ragged L ix e, Mutable r ix e) =>
Comp -> [ListItem ix e] -> Array r ix e
L.fromLists' Comp
Seq
  {-# INLINE fromList #-}
  toList :: Array B ix e -> [Item (Array B ix e)]
toList = Array L ix e -> [ListItem ix e]
forall l. IsList l => l -> [Item l]
GHC.toList (Array L ix e -> [ListItem ix e])
-> (Array B ix e -> Array L ix e)
-> Array B ix e
-> [ListItem ix e]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array B ix e -> Array L ix e
forall ix e r.
(Construct L ix e, Source r ix e) =>
Array r ix e -> Array L ix e
toListArray
  {-# INLINE toList #-}

-----------------------
-- Boxed Normal Form --
-----------------------

-- | Array representation for Boxed elements. This structure is element and
-- spine strict, and elements are always in Normal Form (NF), therefore `NFData`
-- instance is required.
data N = N deriving Int -> N -> ShowS
[N] -> ShowS
N -> String
(Int -> N -> ShowS) -> (N -> String) -> ([N] -> ShowS) -> Show N
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [N] -> ShowS
$cshowList :: [N] -> ShowS
show :: N -> String
$cshow :: N -> String
showsPrec :: Int -> N -> ShowS
$cshowsPrec :: Int -> N -> ShowS
Show

newtype instance Array N ix e = NArray { Array N ix e -> Array B ix e
bArray :: Array B ix e }

instance (Ragged L ix e, Show e, NFData e) => Show (Array N ix e) where
  showsPrec :: Int -> Array N ix e -> ShowS
showsPrec = (Array N ix e -> Array B ix e) -> Int -> Array N ix e -> ShowS
forall r r' ix ix' e.
(Ragged L ix' e, Load r ix e, Source r' ix' e, Show e) =>
(Array r ix e -> Array r' ix' e) -> Int -> Array r ix e -> ShowS
showsArrayPrec Array N ix e -> Array B ix e
forall ix e. Array N ix e -> Array B ix e
bArray
  showList :: [Array N ix e] -> ShowS
showList = [Array N ix e] -> ShowS
forall arr. Show arr => [arr] -> ShowS
showArrayList

instance (Index ix, NFData e) => NFData (Array N ix e) where
  rnf :: Array N ix e -> ()
rnf (NArray barr) = Array B ix e
barr Array B ix e -> () -> ()
forall a ix t. (NFData a, Index ix) => Array B ix a -> t -> t
`deepseqArray` ()
  {-# INLINE rnf #-}

instance (Index ix, NFData e, Eq e) => Eq (Array N ix e) where
  == :: Array N ix e -> Array N ix e -> Bool
(==) = (e -> e -> Bool) -> Array N ix e -> Array N ix e -> Bool
forall r1 ix e1 r2 e2.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> Bool) -> Array r1 ix e1 -> Array r2 ix e2 -> Bool
eqArrays e -> e -> Bool
forall a. Eq a => a -> a -> Bool
(==)
  {-# INLINE (==) #-}

instance (Index ix, NFData e, Ord e) => Ord (Array N ix e) where
  compare :: Array N ix e -> Array N ix e -> Ordering
compare = (e -> e -> Ordering) -> Array N ix e -> Array N ix e -> Ordering
forall r1 ix e1 r2 e2.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> Ordering)
-> Array r1 ix e1 -> Array r2 ix e2 -> Ordering
compareArrays e -> e -> Ordering
forall a. Ord a => a -> a -> Ordering
compare
  {-# INLINE compare #-}


instance (Index ix, NFData e) => Construct N ix e where
  setComp :: Comp -> Array N ix e -> Array N ix e
setComp Comp
c (NArray arr) = Array B ix e -> Array N ix e
forall ix e. Array B ix e -> Array N ix e
NArray (Array B ix e
R:ArrayBixe ix e
arr {bComp :: Comp
bComp = Comp
c})
  {-# INLINE setComp #-}
  makeArray :: Comp -> Sz ix -> (ix -> e) -> Array N ix e
makeArray !Comp
comp !Sz ix
sz ix -> e
f =
    IO (Array N ix e) -> Array N ix e
forall a. IO a -> a
unsafePerformIO (IO (Array N ix e) -> Array N ix e)
-> IO (Array N ix e) -> Array N ix e
forall a b. (a -> b) -> a -> b
$
    Comp -> Sz ix -> (ix -> IO e) -> IO (Array N ix e)
forall r ix e (m :: * -> *).
(MonadUnliftIO m, PrimMonad m, Mutable r ix e) =>
Comp -> Sz ix -> (ix -> m e) -> m (Array r ix e)
generateArray
      Comp
comp
      Sz ix
sz
      (\ !ix
ix ->
         let res :: e
res = ix -> e
f ix
ix
          in e
res e -> IO e -> IO e
forall a b. NFData a => a -> b -> b
`deepseq` e -> IO e
forall (m :: * -> *) a. Monad m => a -> m a
return e
res)
  {-# INLINE makeArray #-}

instance (Index ix, NFData e) => Source N ix e where
  unsafeLinearIndex :: Array N ix e -> Int -> e
unsafeLinearIndex (NArray arr) = Array B ix e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array B ix e
arr
  {-# INLINE unsafeLinearIndex #-}
  unsafeLinearSlice :: Int -> Sz1 -> Array N ix e -> Array N Int e
unsafeLinearSlice Int
i Sz1
k (NArray a) = Array B Int e -> Array N Int e
forall ix e. Array B ix e -> Array N ix e
NArray (Array B Int e -> Array N Int e) -> Array B Int e -> Array N Int e
forall a b. (a -> b) -> a -> b
$ Int -> Sz1 -> Array B ix e -> Array B Int e
forall r ix e.
Source r ix e =>
Int -> Sz1 -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
i Sz1
k Array B ix e
a
  {-# INLINE unsafeLinearSlice #-}


instance Index ix => Resize N ix where
  unsafeResize :: Sz ix' -> Array N ix e -> Array N ix' e
unsafeResize !Sz ix'
sz = Array B ix' e -> Array N ix' e
forall ix e. Array B ix e -> Array N ix e
NArray (Array B ix' e -> Array N ix' e)
-> (Array N ix e -> Array B ix' e) -> Array N ix e -> Array N ix' e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sz ix' -> Array B ix e -> Array B ix' e
forall r ix ix' e.
(Resize r ix, Index ix') =>
Sz ix' -> Array r ix e -> Array r ix' e
unsafeResize Sz ix'
sz (Array B ix e -> Array B ix' e)
-> (Array N ix e -> Array B ix e) -> Array N ix e -> Array B ix' e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
forall ix e. Array N ix e -> Array B ix e
bArray
  {-# INLINE unsafeResize #-}

instance (Index ix, NFData e) => Extract N ix e where
  unsafeExtract :: ix -> Sz ix -> Array N ix e -> Array (R N) ix e
unsafeExtract !ix
sIx !Sz ix
newSz !Array N ix e
arr = ix -> Sz ix -> Array M ix e -> Array (R M) ix e
forall r ix e.
Extract r ix e =>
ix -> Sz ix -> Array r ix e -> Array (R r) ix e
unsafeExtract ix
sIx Sz ix
newSz (Array N ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest Array N ix e
arr)
  {-# INLINE unsafeExtract #-}


instance ( NFData e
         , Index ix
         , Index (Lower ix)
         , Elt M ix e ~ Array M (Lower ix) e
         , Elt N ix e ~ Array M (Lower ix) e
         ) =>
         OuterSlice N ix e where
  unsafeOuterSlice :: Array N ix e -> Int -> Elt N ix e
unsafeOuterSlice = Array M ix e -> Int -> Array M (Lower ix) e
forall r ix e.
OuterSlice r ix e =>
Array r ix e -> Int -> Elt r ix e
unsafeOuterSlice (Array M ix e -> Int -> Array M (Lower ix) e)
-> (Array N ix e -> Array M ix e)
-> Array N ix e
-> Int
-> Array M (Lower ix) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest
  {-# INLINE unsafeOuterSlice #-}

instance ( NFData e
         , Index ix
         , Index (Lower ix)
         , Elt M ix e ~ Array M (Lower ix) e
         , Elt N ix e ~ Array M (Lower ix) e
         ) =>
         InnerSlice N ix e where
  unsafeInnerSlice :: Array N ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt N ix e
unsafeInnerSlice = Array M ix e -> (Sz (Lower ix), Sz1) -> Int -> Array M (Lower ix) e
forall r ix e.
InnerSlice r ix e =>
Array r ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt r ix e
unsafeInnerSlice (Array M ix e
 -> (Sz (Lower ix), Sz1) -> Int -> Array M (Lower ix) e)
-> (Array N ix e -> Array M ix e)
-> Array N ix e
-> (Sz (Lower ix), Sz1)
-> Int
-> Array M (Lower ix) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array M ix e
forall r ix e. Manifest r ix e => Array r ix e -> Array M ix e
toManifest
  {-# INLINE unsafeInnerSlice #-}

instance {-# OVERLAPPING #-} NFData e => Slice N Ix1 e where
  unsafeSlice :: Array N Int e -> Int -> Sz1 -> Dim -> m (Elt N Int e)
unsafeSlice Array N Int e
arr Int
i Sz1
_ Dim
_ = e -> m e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array N Int e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array N Int e
arr Int
i)
  {-# INLINE unsafeSlice #-}


instance (Index ix, NFData e) => Manifest N ix e where

  unsafeLinearIndexM :: Array N ix e -> Int -> e
unsafeLinearIndexM (NArray arr) = Array B ix e -> Int -> e
forall r ix e. Manifest r ix e => Array r ix e -> Int -> e
unsafeLinearIndexM Array B ix e
arr
  {-# INLINE unsafeLinearIndexM #-}


instance (Index ix, NFData e) => Mutable N ix e where
  newtype MArray s N ix e = MNArray { MArray s N ix e -> MArray s B ix e
bmArray :: MArray s B ix e }

  msize :: MArray s N ix e -> Sz ix
msize = MArray s B ix e -> Sz ix
forall r ix e s. Mutable r ix e => MArray s r ix e -> Sz ix
msize (MArray s B ix e -> Sz ix)
-> (MArray s N ix e -> MArray s B ix e) -> MArray s N ix e -> Sz ix
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MArray s N ix e -> MArray s B ix e
forall s ix e. MArray s N ix e -> MArray s B ix e
bmArray
  {-# INLINE msize #-}

  unsafeThaw :: Array N ix e -> m (MArray (PrimState m) N ix e)
unsafeThaw (NArray arr) = MArray (PrimState m) B ix e -> MArray (PrimState m) N ix e
forall s ix e. MArray s B ix e -> MArray s N ix e
MNArray (MArray (PrimState m) B ix e -> MArray (PrimState m) N ix e)
-> m (MArray (PrimState m) B ix e)
-> m (MArray (PrimState m) N ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array B ix e -> m (MArray (PrimState m) B ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array B ix e
arr
  {-# INLINE unsafeThaw #-}

  unsafeFreeze :: Comp -> MArray (PrimState m) N ix e -> m (Array N ix e)
unsafeFreeze Comp
comp (MNArray marr) = Array B ix e -> Array N ix e
forall ix e. Array B ix e -> Array N ix e
NArray (Array B ix e -> Array N ix e)
-> m (Array B ix e) -> m (Array N ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Comp -> MArray (PrimState m) B ix e -> m (Array B ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze Comp
comp MArray (PrimState m) B ix e
marr
  {-# INLINE unsafeFreeze #-}

  unsafeNew :: Sz ix -> m (MArray (PrimState m) N ix e)
unsafeNew Sz ix
sz = MArray (PrimState m) B ix e -> MArray (PrimState m) N ix e
forall s ix e. MArray s B ix e -> MArray s N ix e
MNArray (MArray (PrimState m) B ix e -> MArray (PrimState m) N ix e)
-> m (MArray (PrimState m) B ix e)
-> m (MArray (PrimState m) N ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sz ix -> m (MArray (PrimState m) B ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> m (MArray (PrimState m) r ix e)
unsafeNew Sz ix
sz
  {-# INLINE unsafeNew #-}

  initialize :: MArray (PrimState m) N ix e -> m ()
initialize MArray (PrimState m) N ix e
_ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  {-# INLINE initialize #-}

  unsafeLinearRead :: MArray (PrimState m) N ix e -> Int -> m e
unsafeLinearRead (MNArray ma) = MArray (PrimState m) B ix e -> Int -> m e
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> Int -> m e
unsafeLinearRead MArray (PrimState m) B ix e
ma
  {-# INLINE unsafeLinearRead #-}

  unsafeLinearWrite :: MArray (PrimState m) N ix e -> Int -> e -> m ()
unsafeLinearWrite (MNArray ma) Int
i e
e = e
e e -> m () -> m ()
forall a b. NFData a => a -> b -> b
`deepseq` MArray (PrimState m) B ix e -> Int -> e -> m ()
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> Int -> e -> m ()
unsafeLinearWrite MArray (PrimState m) B ix e
ma Int
i e
e
  {-# INLINE unsafeLinearWrite #-}

instance (Index ix, NFData e) => Load N ix e where
  type R N = M
  size :: Array N ix e -> Sz ix
size = Array B ix e -> Sz ix
forall ix e. Array B ix e -> Sz ix
bSize (Array B ix e -> Sz ix)
-> (Array N ix e -> Array B ix e) -> Array N ix e -> Sz ix
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
forall ix e. Array N ix e -> Array B ix e
bArray
  {-# INLINE size #-}
  getComp :: Array N ix e -> Comp
getComp = Array B ix e -> Comp
forall ix e. Array B ix e -> Comp
bComp (Array B ix e -> Comp)
-> (Array N ix e -> Array B ix e) -> Array N ix e -> Comp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
forall ix e. Array N ix e -> Array B ix e
bArray
  {-# INLINE getComp #-}
  loadArrayM :: Scheduler m () -> Array N ix e -> (Int -> e -> m ()) -> m ()
loadArrayM !Scheduler m ()
scheduler !Array N ix e
arr = Scheduler m () -> Int -> (Int -> e) -> (Int -> e -> m ()) -> m ()
forall (m :: * -> *) b.
Monad m =>
Scheduler m () -> Int -> (Int -> b) -> (Int -> b -> m ()) -> m ()
splitLinearlyWith_ Scheduler m ()
scheduler (Array N ix e -> Int
forall r ix e. Load r ix e => Array r ix e -> Int
elemsCount Array N ix e
arr) (Array N ix e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Array N ix e
arr)
  {-# INLINE loadArrayM #-}

instance (Index ix, NFData e) => StrideLoad N ix e

instance (Index ix, NFData e) => Stream N ix e where
  toStream :: Array N ix e -> Steps Id e
toStream = Array B ix e -> Steps Id e
forall r ix e. Stream r ix e => Array r ix e -> Steps Id e
toStream (Array B ix e -> Steps Id e)
-> (Array N ix e -> Array B ix e) -> Array N ix e -> Steps Id e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
coerce
  {-# INLINE toStream #-}
  toStreamIx :: Array N ix e -> Steps Id (ix, e)
toStreamIx = Array B ix e -> Steps Id (ix, e)
forall r ix e. Stream r ix e => Array r ix e -> Steps Id (ix, e)
toStreamIx (Array B ix e -> Steps Id (ix, e))
-> (Array N ix e -> Array B ix e)
-> Array N ix e
-> Steps Id (ix, e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
coerce
  {-# INLINE toStreamIx #-}


instance ( NFData e
         , IsList (Array L ix e)
         , Nested LN ix e
         , Nested L ix e
         , Ragged L ix e
         ) =>
         IsList (Array N ix e) where
  type Item (Array N ix e) = Item (Array L ix e)
  fromList :: [Item (Array N ix e)] -> Array N ix e
fromList = Comp -> [ListItem ix e] -> Array N ix e
forall r ix e.
(Nested LN ix e, Ragged L ix e, Mutable r ix e) =>
Comp -> [ListItem ix e] -> Array r ix e
L.fromLists' Comp
Seq
  {-# INLINE fromList #-}
  toList :: Array N ix e -> [Item (Array N ix e)]
toList = Array L ix e -> [ListItem ix e]
forall l. IsList l => l -> [Item l]
GHC.toList (Array L ix e -> [ListItem ix e])
-> (Array N ix e -> Array L ix e)
-> Array N ix e
-> [ListItem ix e]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array L ix e
forall ix e r.
(Construct L ix e, Source r ix e) =>
Array r ix e -> Array L ix e
toListArray
  {-# INLINE toList #-}


----------------------
-- Helper functions --
----------------------

uninitialized :: a
uninitialized :: a
uninitialized = Uninitialized -> a
forall a e. Exception e => e -> a
throw Uninitialized
Uninitialized

---------------------
-- WHNF conversion --
---------------------

-- | /O(1)/ - Unwrap boxed array. This will discard any possible slicing that has been
-- applied to the array.
--
-- @since 0.2.1
unwrapArray :: Array B ix e -> A.Array e
unwrapArray :: Array B ix e -> Array e
unwrapArray = Array B ix e -> Array e
forall ix e. Array B ix e -> Array e
bData
{-# INLINE unwrapArray #-}

-- | /O(n)/ - Wrap a boxed array and evaluate all elements to a WHNF.
--
-- @since 0.2.1
evalArray ::
     Comp -- ^ Computation strategy
  -> A.Array e -- ^ Lazy boxed array from @primitive@ package.
  -> Array B Ix1 e
evalArray :: Comp -> Array e -> Array B Int e
evalArray = (Array B Int e -> Array B Int e)
-> Comp -> Array e -> Array B Int e
forall e a. (Array B Int e -> a) -> Comp -> Array e -> a
fromArraySeq (\Array B Int e
a -> Array B Int e
a Array B Int e -> Array B Int e -> Array B Int e
forall ix a t. Index ix => Array B ix a -> t -> t
`seqArray` Array B Int e
a)
{-# INLINE evalArray #-}


-- | /O(1)/ - Unwrap mutable boxed array. This will discard any possible slicing that has been
-- applied to the array.
--
-- @since 0.2.1
unwrapMutableArray :: MArray s B ix e -> A.MutableArray s e
unwrapMutableArray :: MArray s B ix e -> MutableArray s e
unwrapMutableArray (MBArray _ _ marr) = MutableArray s e
marr
{-# INLINE unwrapMutableArray #-}


-- | /O(n)/ - Wrap mutable boxed array and evaluate all elements to WHNF.
--
-- @since 0.2.1
evalMutableArray ::
     PrimMonad m
  => A.MutableArray (PrimState m) e -- ^ Mutable array that will get wrapped
  -> m (MArray (PrimState m) B Ix1 e)
evalMutableArray :: MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
evalMutableArray = (e -> m () -> m ())
-> MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
forall (m :: * -> *) e a.
PrimMonad m =>
(e -> m () -> m a)
-> MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
fromMutableArraySeq e -> m () -> m ()
seq
{-# INLINE evalMutableArray #-}

-------------------
-- NF conversion --
-------------------

-- | /O(1)/ - Unwrap a fully evaluated boxed array. This will discard any possible slicing
-- that has been applied to the array.
--
-- @since 0.2.1
unwrapNormalFormArray :: Array N ix e -> A.Array e
unwrapNormalFormArray :: Array N ix e -> Array e
unwrapNormalFormArray = Array B ix e -> Array e
forall ix e. Array B ix e -> Array e
bData (Array B ix e -> Array e)
-> (Array N ix e -> Array B ix e) -> Array N ix e -> Array e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array N ix e -> Array B ix e
forall ix e. Array N ix e -> Array B ix e
bArray
{-# INLINE unwrapNormalFormArray #-}

-- | /O(n)/ - Wrap a boxed array and evaluate all elements to a Normal Form (NF).
--
-- @since 0.2.1
evalNormalFormArray ::
     NFData e
  => Comp -- ^ Computation strategy
  -> A.Array e -- ^ Lazy boxed array
  -> Array N Ix1 e
evalNormalFormArray :: Comp -> Array e -> Array N Int e
evalNormalFormArray = (Array B Int e -> Array N Int e)
-> Comp -> Array e -> Array N Int e
forall e a. (Array B Int e -> a) -> Comp -> Array e -> a
fromArraySeq (\Array B Int e
a -> Array B Int e
a Array B Int e -> Array N Int e -> Array N Int e
forall a ix t. (NFData a, Index ix) => Array B ix a -> t -> t
`deepseqArray` Array B Int e -> Array N Int e
forall ix e. Array B ix e -> Array N ix e
NArray Array B Int e
a)
{-# INLINE evalNormalFormArray #-}


-- | /O(1)/ - Unwrap a fully evaluated mutable boxed array. This will discard any possible
-- slicing that has been applied to the array.
--
-- @since 0.2.1
unwrapNormalFormMutableArray :: MArray s N ix e -> A.MutableArray s e
unwrapNormalFormMutableArray :: MArray s N ix e -> MutableArray s e
unwrapNormalFormMutableArray (MNArray marr) = MArray s B ix e -> MutableArray s e
forall s ix e. MArray s B ix e -> MutableArray s e
unwrapMutableArray MArray s B ix e
marr
{-# INLINE unwrapNormalFormMutableArray #-}


-- | /O(n)/ - Wrap mutable boxed array and evaluate all elements to NF.
--
-- @since 0.2.1
evalNormalFormMutableArray ::
     (PrimMonad m, NFData e)
  => A.MutableArray (PrimState m) e
  -> m (MArray (PrimState m) N Ix1 e)
evalNormalFormMutableArray :: MutableArray (PrimState m) e -> m (MArray (PrimState m) N Int e)
evalNormalFormMutableArray MutableArray (PrimState m) e
marr = MArray (PrimState m) B Int e -> MArray (PrimState m) N Int e
forall s ix e. MArray s B ix e -> MArray s N ix e
MNArray (MArray (PrimState m) B Int e -> MArray (PrimState m) N Int e)
-> m (MArray (PrimState m) B Int e)
-> m (MArray (PrimState m) N Int e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (e -> m () -> m ())
-> MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
forall (m :: * -> *) e a.
PrimMonad m =>
(e -> m () -> m a)
-> MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
fromMutableArraySeq e -> m () -> m ()
forall a b. NFData a => a -> b -> b
deepseq MutableArray (PrimState m) e
marr
{-# INLINE evalNormalFormMutableArray #-}


----------------------
-- Helper functions --
----------------------

fromMutableArraySeq ::
     PrimMonad m
  => (e -> m () -> m a)
  -> A.MutableArray (PrimState m) e
  -> m (MArray (PrimState m) B Ix1 e)
fromMutableArraySeq :: (e -> m () -> m a)
-> MutableArray (PrimState m) e -> m (MArray (PrimState m) B Int e)
fromMutableArraySeq e -> m () -> m a
with MutableArray (PrimState m) e
ma = do
  let !sz :: Int
sz = MutableArray (PrimState m) e -> Int
forall s a. MutableArray s a -> Int
sizeofMutableArray MutableArray (PrimState m) e
ma
  Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
0 (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (MutableArray (PrimState m) e -> Int -> m e
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
A.readArray MutableArray (PrimState m) e
ma (Int -> m e) -> (e -> m a) -> Int -> m a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (e -> m () -> m a
`with` () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()))
  MArray (PrimState m) B Int e -> m (MArray (PrimState m) B Int e)
forall (m :: * -> *) a. Monad m => a -> m a
return (MArray (PrimState m) B Int e -> m (MArray (PrimState m) B Int e))
-> MArray (PrimState m) B Int e -> m (MArray (PrimState m) B Int e)
forall a b. (a -> b) -> a -> b
$! Sz1
-> Int
-> MutableArray (PrimState m) e
-> MArray (PrimState m) B Int e
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz Int
sz) Int
0 MutableArray (PrimState m) e
ma
{-# INLINE fromMutableArraySeq #-}

fromArraySeq ::
     (Array B Ix1 e -> a)
  -> Comp
  -> A.Array e
  -> a
fromArraySeq :: (Array B Int e -> a) -> Comp -> Array e -> a
fromArraySeq Array B Int e -> a
with Comp
comp Array e
barr = Array B Int e -> a
with (Comp -> Sz1 -> Int -> Array e -> Array B Int e
forall ix e. Comp -> Sz ix -> Int -> Array e -> Array B ix e
BArray Comp
comp (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz (Array e -> Int
forall a. Array a -> Int
sizeofArray Array e
barr)) Int
0 Array e
barr)
{-# INLINE fromArraySeq #-}


seqArray :: Index ix => Array B ix a -> t -> t
seqArray :: Array B ix a -> t -> t
seqArray !Array B ix a
arr t
t = (() -> a -> ())
-> () -> (() -> () -> ()) -> () -> Array B ix a -> ()
forall r ix e a b.
Source r ix e =>
(a -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> b
foldlInternal ((a -> () -> ()) -> () -> a -> ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> () -> ()
seq) () ((() -> () -> ()) -> () -> () -> ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip () -> () -> ()
seq) () Array B ix a
arr () -> t -> t
`seq` t
t
{-# INLINE seqArray #-}


deepseqArray :: (NFData a, Index ix) => Array B ix a -> t -> t
deepseqArray :: Array B ix a -> t -> t
deepseqArray !Array B ix a
arr t
t = (() -> a -> ())
-> () -> (() -> () -> ()) -> () -> Array B ix a -> ()
forall r ix e a b.
Source r ix e =>
(a -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> b
foldlInternal ((a -> () -> ()) -> () -> a -> ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> () -> ()
forall a b. NFData a => a -> b -> b
deepseq) () ((() -> () -> ()) -> () -> () -> ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip () -> () -> ()
seq) () Array B ix a
arr () -> t -> t
`seq` t
t
{-# INLINE deepseqArray #-}


-- | /O(n)/ - Compute all elements of a boxed array to NF (normal form)
--
-- @since 0.5.0
unwrapNormalForm :: Array N ix e -> Array B ix e
unwrapNormalForm :: Array N ix e -> Array B ix e
unwrapNormalForm = Array N ix e -> Array B ix e
coerce
{-# INLINE unwrapNormalForm #-}

-- | /O(n)/ - Compute all elements of a boxed array to NF (normal form)
--
-- @since 0.5.0
evalNormalForm :: (Index ix, NFData e) => Array B ix e -> Array N ix e
evalNormalForm :: Array B ix e -> Array N ix e
evalNormalForm Array B ix e
arr = Array B ix e
arr Array B ix e -> Array N ix e -> Array N ix e
forall a ix t. (NFData a, Index ix) => Array B ix a -> t -> t
`deepseqArray` Array B ix e -> Array N ix e
forall ix e. Array B ix e -> Array N ix e
NArray Array B ix e
arr
{-# INLINE evalNormalForm #-}

-- | /O(1)/ - Converts a boxed `Array` into a `VB.Vector`.
--
-- @since 0.5.0
toBoxedVector :: Index ix => Array B ix a -> VB.Vector a
toBoxedVector :: Array B ix a -> Vector a
toBoxedVector Array B ix a
arr = (forall s. ST s (Vector a)) -> Vector a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Vector a)) -> Vector a)
-> (forall s. ST s (Vector a)) -> Vector a
forall a b. (a -> b) -> a -> b
$ MVector s a -> ST s (Vector a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
VB.unsafeFreeze (MVector s a -> ST s (Vector a))
-> (MArray s B ix a -> MVector s a)
-> MArray s B ix a
-> ST s (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MArray s B ix a -> MVector s a
forall ix s a. Index ix => MArray s B ix a -> MVector s a
toBoxedMVector (MArray s B ix a -> ST s (Vector a))
-> ST s (MArray s B ix a) -> ST s (Vector a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Array B ix a -> ST s (MArray (PrimState (ST s)) B ix a)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array B ix a
arr
{-# INLINE toBoxedVector #-}

-- | /O(1)/ - Converts a boxed `MArray` into a `VMB.MVector`.
--
-- @since 0.5.0
toBoxedMVector :: Index ix => MArray s B ix a -> MVB.MVector s a
toBoxedMVector :: MArray s B ix a -> MVector s a
toBoxedMVector (MBArray sz o marr) = Int -> Int -> MutableArray s a -> MVector s a
forall s a. Int -> Int -> MutableArray s a -> MVector s a
MVB.MVector Int
o (Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem Sz ix
sz) MutableArray s a
marr
{-# INLINE toBoxedMVector #-}

-- | /O(n)/ - Convert a boxed vector and evaluate all elements to WHNF. Computation
-- strategy will be respected during evaluation
--
-- @since 0.5.0
evalBoxedVector :: Comp -> VB.Vector a -> Array B Ix1 a
evalBoxedVector :: Comp -> Vector a -> Array B Int a
evalBoxedVector Comp
comp Vector a
v = Array B Int a
arr Array B Int a -> Array B Int a -> Array B Int a
forall ix a t. Index ix => Array B ix a -> t -> t
`seqArray` Array B Int a
arr
  where
    arr :: Array B Int a
arr = Comp -> Array B Int a -> Array B Int a
forall r ix e.
Construct r ix e =>
Comp -> Array r ix e -> Array r ix e
setComp Comp
comp (Array B Int a -> Array B Int a) -> Array B Int a -> Array B Int a
forall a b. (a -> b) -> a -> b
$ Vector a -> Array B Int a
forall a. Vector a -> Array B Int a
unsafeFromBoxedVector Vector a
v
{-# INLINE evalBoxedVector #-}


-- | /O(n)/ - Convert mutable boxed vector and evaluate all elements to WHNF
-- sequentially. Both keep pointing to the same memory
--
-- @since 0.5.0
evalBoxedMVector :: PrimMonad m => MVB.MVector (PrimState m) a -> m (MArray (PrimState m) B Ix1 a)
evalBoxedMVector :: MVector (PrimState m) a -> m (MArray (PrimState m) B Int a)
evalBoxedMVector (MVB.MVector Int
o Int
k MutableArray (PrimState m) a
ma) = do
  let marr :: MArray (PrimState m) B Int a
marr = Sz1
-> Int
-> MutableArray (PrimState m) a
-> MArray (PrimState m) B Int a
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz Int
k) Int
o MutableArray (PrimState m) a
ma
  Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m ()) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
o (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
k) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (MutableArray (PrimState m) a -> Int -> m a
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
A.readArray MutableArray (PrimState m) a
ma (Int -> m a) -> (a -> m ()) -> Int -> m ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> m () -> m ()
`seq` () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()))
  MArray (PrimState m) B Int a -> m (MArray (PrimState m) B Int a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure MArray (PrimState m) B Int a
marr
{-# INLINE evalBoxedMVector #-}


-- | /O(n)/ - Cast a boxed vector without touching any elements. It is unsafe because it
-- violates the invariant that all elements of `B` array are in WHNF.
--
-- @since 0.5.0
unsafeFromBoxedVector :: VB.Vector a -> Array B Ix1 a
unsafeFromBoxedVector :: Vector a -> Array B Int a
unsafeFromBoxedVector Vector a
v =
  (forall s. ST s (Array B Int a)) -> Array B Int a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Array B Int a)) -> Array B Int a)
-> (forall s. ST s (Array B Int a)) -> Array B Int a
forall a b. (a -> b) -> a -> b
$ do
    MVB.MVector Int
o Int
k MutableArray s a
ma <- Vector a -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
VB.unsafeThaw Vector a
v
    Comp -> MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze Comp
Seq (MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a))
-> MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a)
forall a b. (a -> b) -> a -> b
$ Sz1 -> Int -> MutableArray s a -> MArray s B Int a
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz Int
k) Int
o MutableArray s a
ma
{-# INLINE unsafeFromBoxedVector #-}

-- | /O(n)/ - Cast a boxed array. It is unsafe because it violates the invariant that all
-- elements of `N` array are in NF.
--
-- @since 0.5.0
unsafeBoxedArray :: A.Array e -> Array B Ix1 e
unsafeBoxedArray :: Array e -> Array B Int e
unsafeBoxedArray = (Array B Int e -> Array B Int e)
-> Comp -> Array e -> Array B Int e
forall e a. (Array B Int e -> a) -> Comp -> Array e -> a
fromArraySeq Array B Int e -> Array B Int e
forall a. a -> a
id Comp
Seq
{-# INLINE unsafeBoxedArray #-}


-- | /O(n)/ - Cast a boxed array. It is unsafe because it violates the invariant that all
-- elements of `N` array are in NF.
--
-- @since 0.5.0
unsafeNormalBoxedArray :: Array B ix e -> Array N ix e
unsafeNormalBoxedArray :: Array B ix e -> Array N ix e
unsafeNormalBoxedArray = Array B ix e -> Array N ix e
coerce
{-# INLINE unsafeNormalBoxedArray #-}

-- | /O(n)/ - Convert mutable boxed vector and evaluate all elements to WHNF
-- sequentially. Both keep pointing to the same memory
--
-- @since 0.5.0
evalNormalBoxedMVector ::
     (NFData a, PrimMonad m) => MVB.MVector (PrimState m) a -> m (MArray (PrimState m) N Ix1 a)
evalNormalBoxedMVector :: MVector (PrimState m) a -> m (MArray (PrimState m) N Int a)
evalNormalBoxedMVector (MVB.MVector Int
o Int
k MutableArray (PrimState m) a
ma) = do
  let marr :: MArray (PrimState m) N Int a
marr = MArray (PrimState m) B Int a -> MArray (PrimState m) N Int a
forall s ix e. MArray s B ix e -> MArray s N ix e
MNArray (Sz1
-> Int
-> MutableArray (PrimState m) a
-> MArray (PrimState m) B Int a
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz Int
k) Int
o MutableArray (PrimState m) a
ma)
  Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m ()) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
o (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
k) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (MutableArray (PrimState m) a -> Int -> m a
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
A.readArray MutableArray (PrimState m) a
ma (Int -> m a) -> (a -> m ()) -> Int -> m ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> m () -> m ()
forall a b. NFData a => a -> b -> b
`deepseq` () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()))
  MArray (PrimState m) N Int a -> m (MArray (PrimState m) N Int a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure MArray (PrimState m) N Int a
marr
{-# INLINE evalNormalBoxedMVector #-}

-- | /O(n)/ - Convert a boxed vector and evaluate all elements to WHNF. Computation
-- strategy will be respected during evaluation
--
-- @since 0.5.0
evalNormalBoxedVector :: NFData a => Comp -> VB.Vector a -> Array N Ix1 a
evalNormalBoxedVector :: Comp -> Vector a -> Array N Int a
evalNormalBoxedVector Comp
comp Vector a
v =
  (forall s. ST s (Array N Int a)) -> Array N Int a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Array N Int a)) -> Array N Int a)
-> (forall s. ST s (Array N Int a)) -> Array N Int a
forall a b. (a -> b) -> a -> b
$ do
    MVB.MVector Int
o Int
k MutableArray s a
ma <- Vector a -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
VB.unsafeThaw Vector a
v
    Array B Int a
arr <- Comp -> MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze Comp
comp (MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a))
-> MArray (PrimState (ST s)) B Int a -> ST s (Array B Int a)
forall a b. (a -> b) -> a -> b
$ Sz1 -> Int -> MutableArray s a -> MArray s B Int a
forall s ix e. Sz ix -> Int -> MutableArray s e -> MArray s B ix e
MBArray (Int -> Sz1
forall ix. ix -> Sz ix
SafeSz Int
k) Int
o MutableArray s a
ma
    Array B Int a
arr Array B Int a -> ST s (Array N Int a) -> ST s (Array N Int a)
forall a ix t. (NFData a, Index ix) => Array B ix a -> t -> t
`deepseqArray` Array N Int a -> ST s (Array N Int a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array B Int a -> Array N Int a
forall ix e. Array B ix e -> Array N ix e
NArray Array B Int a
arr)
{-# INLINE evalNormalBoxedVector #-}