dph-lifted-base-0.6.0.1: Data/Array/Parallel/PArr.hs
{-# OPTIONS_GHC -funbox-strict-fields #-}
{-# OPTIONS_HADDOCK hide #-}
-- NOTE NOTE NOTE
-- This file is IDENTICAL to the one in dph-lifted-boxed.
-- If you update one then update the other as well.
-- | Unvectorised functions that work directly on parallel arrays of [::] type.
-- These are used internally in the DPH library, but the user never sees them.
-- Only vectorised functions are visible in the DPH client programs.
--
module Data.Array.Parallel.PArr
( PArr
, emptyPArr
, replicatePArr
, singletonPArr
, indexPArr
, headPArr
, lengthPArr)
where
import GHC.ST
import GHC.Base
import GHC.PArr
-- | Construct an empty array, with no elements.
emptyPArr :: PArr a
emptyPArr = replicatePArr 0 undefined
{-# NOINLINE emptyPArr #-}
-- | Construct an array with a single element.
singletonPArr :: a -> PArr a
singletonPArr e = replicatePArr 1 e
{-# NOINLINE singletonPArr #-}
-- | Construct an array by replicating the given element some number of times.
replicatePArr :: Int -> a -> PArr a
replicatePArr n e
= runST (do
marr# <- newArray n e
mkPArr n marr#)
{-# NOINLINE replicatePArr #-}
-- | Take the length of an array.
lengthPArr :: PArr a -> Int
lengthPArr (PArr n _) = n
{-# NOINLINE lengthPArr #-}
-- | Lookup a single element from the source array.
indexPArr :: PArr e -> Int -> e
indexPArr (PArr n arr#) i@(I# i#)
| i >= 0 && i < n
= case indexArray# arr# i# of (# e #) -> e
| otherwise
= error $ "indexPArr: out of bounds parallel array index; "
++ "idx = " ++ show i ++ ", arr len = "
++ show n
{-# NOINLINE indexPArr #-}
-- | Take the first element of the source array,
-- or `error` if there isn't one.
headPArr :: PArr a -> a
headPArr arr = indexPArr arr 0
{-# NOINLINE headPArr #-}
-------------------------------------------------------------------------------
-- | Internally used mutable boxed arrays
data MPArr s e = MPArr !Int (MutableArray# s e)
-- | Allocate a new mutable array that is pre-initialised with a given value
newArray :: Int -> e -> ST s (MPArr s e)
newArray n@(I# n#) e = ST $ \s1# ->
case newArray# n# e s1# of { (# s2#, marr# #) ->
(# s2#, MPArr n marr# #)}
{-# INLINE newArray #-}
-- | Convert a mutable array into the external parallel array representation
mkPArr :: Int -> MPArr s e -> ST s (PArr e)
mkPArr n (MPArr _ marr#) = ST $ \s1# ->
case unsafeFreezeArray# marr# s1# of { (# s2#, arr# #) ->
(# s2#, PArr n arr# #) }
{-# INLINE mkPArr #-}