massiv-1.0.2.0: src/Data/Massiv/Array/Manifest/Unboxed.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
-- Module : Data.Massiv.Array.Manifest.Unboxed
-- Copyright : (c) Alexey Kuleshevich 2018-2022
-- License : BSD3
-- Maintainer : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability : experimental
-- Portability : non-portable
--
module Data.Massiv.Array.Manifest.Unboxed
( U (..)
, Unbox
, Array(..)
, MArray(..)
, toUnboxedVector
, toUnboxedMVector
, fromUnboxedVector
, fromUnboxedMVector
) where
import Control.DeepSeq (NFData(..), deepseq)
import Control.Monad.Primitive (stToPrim)
import Data.Massiv.Array.Delayed.Pull (D, compareArrays, eqArrays)
import Data.Massiv.Array.Manifest.Internal
import Data.Massiv.Array.Manifest.List as A
import Data.Massiv.Array.Mutable
import Data.Massiv.Core.Common
import Data.Massiv.Core.List
import Data.Massiv.Core.Operations
import Data.Massiv.Vector.Stream as S (isteps, steps)
import qualified Data.Vector.Generic.Mutable as VGM
import Data.Vector.Unboxed (Unbox)
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as MVU
import GHC.Exts as GHC (IsList(..))
import Prelude hiding (mapM)
import System.IO.Unsafe (unsafePerformIO)
#include "massiv.h"
-- | Representation for `Unbox`ed elements
data U = U deriving Show
data instance Array U ix e = UArray { uComp :: !Comp
, uSize :: !(Sz ix)
, uData :: !(VU.Vector e)
}
data instance MArray s U ix e = MUArray !(Sz ix) !(VU.MVector s e)
instance (Ragged L ix e, Show e, Unbox e) => Show (Array U ix e) where
showsPrec = showsArrayPrec id
showList = showArrayList
instance NFData ix => NFData (Array U ix e) where
rnf (UArray c sz v) = c `deepseq` sz `deepseq` v `deepseq` ()
{-# INLINE rnf #-}
instance NFData ix => NFData (MArray s U ix e) where
rnf (MUArray sz mv) = sz `deepseq` mv `deepseq` ()
{-# INLINE rnf #-}
instance Strategy U where
getComp = uComp
{-# INLINE getComp #-}
setComp c arr = arr { uComp = c }
{-# INLINE setComp #-}
repr = U
instance (Unbox e, Eq e, Index ix) => Eq (Array U ix e) where
(==) = eqArrays (==)
{-# INLINE (==) #-}
instance (Unbox e, Ord e, Index ix) => Ord (Array U ix e) where
compare = compareArrays compare
{-# INLINE compare #-}
instance Unbox e => Source U e where
unsafeLinearIndex (UArray _ _ v) =
INDEX_CHECK("(Source U ix e).unsafeLinearIndex", Sz . VU.length, VU.unsafeIndex) v
{-# INLINE unsafeLinearIndex #-}
unsafeOuterSlice (UArray c _ v) szL i =
let k = totalElem szL
in UArray c szL $ VU.unsafeSlice (i * k) k v
{-# INLINE unsafeOuterSlice #-}
unsafeLinearSlice i k (UArray c _ v) = UArray c k $ VU.unsafeSlice i (unSz k) v
{-# INLINE unsafeLinearSlice #-}
instance Index ix => Shape U ix where
maxLinearSize = Just . SafeSz . elemsCount
{-# INLINE maxLinearSize #-}
instance Size U where
size = uSize
{-# INLINE size #-}
unsafeResize !sz !arr = arr { uSize = sz }
{-# INLINE unsafeResize #-}
instance (Unbox e, Index ix) => Load U ix e where
makeArray comp sz f = compute (makeArray comp sz f :: Array D ix e)
{-# INLINE makeArray #-}
makeArrayLinear !comp !sz f = unsafePerformIO $ generateArrayLinear comp sz (pure . f)
{-# INLINE makeArrayLinear #-}
replicate comp !sz !e = runST (newMArray sz e >>= unsafeFreeze comp)
{-# INLINE replicate #-}
iterArrayLinearST_ !scheduler !arr =
splitLinearlyWith_ scheduler (elemsCount arr) (unsafeLinearIndex arr)
{-# INLINE iterArrayLinearST_ #-}
instance (Unbox e, Index ix) => StrideLoad U ix e
instance Unbox e => Manifest U e where
unsafeLinearIndexM (UArray _ _ v) =
INDEX_CHECK("(Manifest U ix e).unsafeLinearIndexM", Sz . VU.length, VU.unsafeIndex) v
{-# INLINE unsafeLinearIndexM #-}
sizeOfMArray (MUArray sz _) = sz
{-# INLINE sizeOfMArray #-}
unsafeResizeMArray sz (MUArray _ mv) = MUArray sz mv
{-# INLINE unsafeResizeMArray #-}
unsafeLinearSliceMArray i k (MUArray _ mv) = MUArray k $ MVU.unsafeSlice i (unSz k) mv
{-# INLINE unsafeLinearSliceMArray #-}
unsafeThaw (UArray _ sz v) = MUArray sz <$> VU.unsafeThaw v
{-# INLINE unsafeThaw #-}
unsafeFreeze comp (MUArray sz v) = UArray comp sz <$> VU.unsafeFreeze v
{-# INLINE unsafeFreeze #-}
unsafeNew sz = MUArray sz <$> MVU.unsafeNew (totalElem sz)
{-# INLINE unsafeNew #-}
initialize (MUArray _ marr) = stToPrim (VGM.basicInitialize marr)
{-# INLINE initialize #-}
unsafeLinearCopy (MUArray _ mvFrom) iFrom (MUArray _ mvTo) iTo (Sz k) =
MVU.unsafeCopy (MVU.unsafeSlice iTo k mvTo) (MVU.unsafeSlice iFrom k mvFrom)
{-# INLINE unsafeLinearCopy #-}
unsafeLinearRead (MUArray _ mv) =
INDEX_CHECK("(Manifest U ix e).unsafeLinearRead", Sz . MVU.length, MVU.unsafeRead) mv
{-# INLINE unsafeLinearRead #-}
unsafeLinearWrite (MUArray _ mv) =
INDEX_CHECK("(Manifest U ix e).unsafeLinearWrite", Sz . MVU.length, MVU.unsafeWrite) mv
{-# INLINE unsafeLinearWrite #-}
unsafeLinearGrow (MUArray _ mv) sz = MUArray sz <$> MVU.unsafeGrow mv (totalElem sz)
{-# INLINE unsafeLinearGrow #-}
instance (Index ix, Unbox e) => Stream U ix e where
toStream = S.steps
{-# INLINE toStream #-}
toStreamIx = S.isteps
{-# INLINE toStreamIx #-}
instance (Unbox e, IsList (Array L ix e), Ragged L ix e) => IsList (Array U ix e) where
type Item (Array U ix e) = Item (Array L ix e)
fromList = A.fromLists' Seq
{-# INLINE fromList #-}
toList = GHC.toList . toListArray
{-# INLINE toList #-}
instance (VU.Unbox e, Num e) => FoldNumeric U e where
unsafeDotProduct = defaultUnsafeDotProduct
{-# INLINE unsafeDotProduct #-}
powerSumArray = defaultPowerSumArray
{-# INLINE powerSumArray #-}
foldArray = defaultFoldArray
{-# INLINE foldArray #-}
instance (VU.Unbox e, Num e) => Numeric U e where
unsafeLiftArray = defaultUnsafeLiftArray
{-# INLINE unsafeLiftArray #-}
unsafeLiftArray2 = defaultUnsafeLiftArray2
{-# INLINE unsafeLiftArray2 #-}
-- | /O(1)/ - Unwrap unboxed array and pull out the underlying unboxed vector.
--
-- @since 0.2.1
toUnboxedVector :: Array U ix e -> VU.Vector e
toUnboxedVector = uData
{-# INLINE toUnboxedVector #-}
-- | /O(1)/ - Unwrap unboxed mutable array and pull out the underlying unboxed mutable vector.
--
-- @since 0.2.1
toUnboxedMVector :: MArray s U ix e -> VU.MVector s e
toUnboxedMVector (MUArray _ mv) = mv
{-# INLINE toUnboxedMVector #-}
-- | /O(1)/ - Wrap an unboxed vector and produce an unboxed flat array.
--
-- @since 0.6.0
fromUnboxedVector :: VU.Unbox e => Comp -> VU.Vector e -> Vector U e
fromUnboxedVector comp v = UArray comp (SafeSz (VU.length v)) v
{-# INLINE fromUnboxedVector #-}
-- | /O(1)/ - Wrap an unboxed mutable vector and produce a mutable unboxed flat array.
--
-- @since 0.5.0
fromUnboxedMVector :: Unbox e => VU.MVector s e -> MVector s U e
fromUnboxedMVector mv = MUArray (SafeSz (MVU.length mv)) mv
{-# INLINE fromUnboxedMVector #-}