----------------------------------------------------------------------------- -- | -- Module : Data.Array.Parallel.Unlifted.Sequential.Segmented.SUArr -- Copyright : (c) [2001..2002] Manuel M T Chakravarty & Gabriele Keller -- (c) 2006 Manuel M T Chakravarty & Roman Leshchinskiy -- License : see libraries/ndp/LICENSE -- -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au> -- Stability : internal -- Portability : portable -- -- Description --------------------------------------------------------------- -- -- This module defines segmented arrays in terms of unsegmented ones. -- -- Todo ---------------------------------------------------------------------- -- {-# LANGUAGE CPP #-} #include "fusion-phases.h" module Data.Array.Parallel.Unlifted.Sequential.Segmented.SUArr ( -- * Array types SUArr, MSUArr, -- * Basic operations on segmented parallel arrays lengthSU, lengthsSU,indicesSU, segdSU, flattenSU, (>:), newMSU, unsafeFreezeMSU, -- * Segment descriptors module Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd ) where -- friends import Data.Array.Parallel.Base ( ST) import Data.Array.Parallel.Unlifted.Sequential.Flat ( UA, UArr, MUArr, (!:), newMU, unsafeFreezeMU) import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd import Control.Monad ( liftM2) infixr 9 >: -- |Segmented arrays -- ----------------- -- |Segmented arrays (only one level of segmentation) -- -- NOTE: We do *not* make this strict in the arrays. This allows GHC to -- eliminate construction/deconstruction of segmented arrays. -- TODO: Is this ok? data SUArr e = SUArr USegd (UArr e) data MSUArr e s = MSUArr (MUSegd s) (MUArr e s) -- |Operations on segmented arrays -- ------------------------------- -- |Yield the segment descriptor -- segdSU :: UA e => SUArr e -> USegd {-# INLINE_U segdSU #-} segdSU (SUArr segd _) = segd -- |Yield the flat data array -- flattenSU :: UA e => SUArr e -> UArr e {-# INLINE_U flattenSU #-} flattenSU (SUArr _ a) = a -- |Yield the number of segments. -- lengthSU :: UA e => SUArr e -> Int {-# INLINE_U lengthSU #-} lengthSU = lengthUSegd . segdSU -- |Yield the lengths of the segments. -- lengthsSU :: UA e => SUArr e -> UArr Int {-# INLINE_U lengthsSU #-} lengthsSU = lengthsUSegd . segdSU -- |Yield the starting indices of the segments. -- indicesSU :: UA e => SUArr e -> UArr Int {-# INLINE_U indicesSU #-} indicesSU = indicesUSegd . segdSU -- |Compose a nested array. -- (>:) :: UA a => USegd -> UArr a -> SUArr a {-# INLINE (>:) #-} (>:) = SUArr -- |Operations on mutable segmented arrays -- --------------------------------------- -- |Allocate a segmented parallel array (providing the number of segments and -- number of base elements). -- newMSU :: UA e => Int -> Int -> ST s (MSUArr e s) {-# INLINE_U newMSU #-} newMSU nsegd n = liftM2 MSUArr (newMUSegd nsegd) (newMU n) -- |Convert a mutable segmented array into an immutable one. -- unsafeFreezeMSU :: UA e => MSUArr e s -> Int -> ST s (SUArr e) {-# INLINE_U unsafeFreezeMSU #-} unsafeFreezeMSU (MSUArr msegd ma) n = do segd <- unsafeFreezeMUSegd msegd n let n' = if n == 0 then 0 else indicesUSegd segd !: (n - 1) + lengthsUSegd segd !: (n - 1) a <- unsafeFreezeMU ma n' return $ SUArr segd a