module Data.Array.Parallel.PArray
( PArray
, valid
, nf
, empty
, singleton, singletonl
, replicate, replicatel, replicates, replicates'
, append, appendl
, concat, concatl
, unconcat
, nestUSegd
, length, lengthl
, index, indexl
, extract, extracts, extracts'
, slice, slicel
, takeUSegd
, pack, packl
, packByTag
, combine2
, enumFromTo, enumFromTol
, zip, zipl
, unzip, unzipl
, fromVector, toVector
, fromList, toList
, fromUArray, toUArray
, fromUArray2)
where
import Data.Array.Parallel.Base (Tag)
import Data.Vector (Vector)
import qualified Data.Array.Parallel.Unlifted as U
import qualified Data.Vector as V
import qualified Prelude as P
import Control.Monad
import GHC.Exts
import Prelude hiding
( replicate, length, concat
, enumFromTo
, zip, unzip)
here :: String -> String
here str = "Data.Array.Parallel.PArray." ++ str
die :: String -> String -> a
die fn str = error (here $ fn ++ " " ++ str)
type PArray a
= Vector a
lift1 :: (a -> b) -> PArray a -> PArray b
lift1 f vec
= V.map f vec
lift2 :: (a -> b -> c) -> PArray a -> PArray b -> PArray c
lift2 f vec1 vec2
| V.length vec1 /= V.length vec2
= die "lift2" "length mismatch"
| otherwise
= V.zipWith f vec1 vec2
lift3 :: (a -> b -> c -> d) -> PArray a -> PArray b -> PArray c -> PArray d
lift3 f vec1 vec2 vec3
| V.length vec1 /= V.length vec2
|| V.length vec1 /= V.length vec3
= die "lift3" "length mismatch"
| otherwise
= V.zipWith3 f vec1 vec2 vec3
valid :: PArray a -> Bool
valid _ = True
nf :: PArray a -> ()
nf _ = ()
empty :: PArray a
empty = V.empty
singleton :: a -> PArray a
singleton = V.singleton
singletonl :: PArray a -> PArray (PArray a)
singletonl = lift1 singleton
replicate :: Int -> a -> PArray a
replicate = V.replicate
replicatel :: PArray Int -> PArray a -> PArray (PArray a)
replicatel = lift2 replicate
replicates :: U.Segd -> PArray a -> PArray a
replicates segd vec
| V.length vec /= U.lengthSegd segd
= die "replicates" $ unlines
[ "segd length mismatch"
, " segd length = " ++ (show $ U.lengthSegd segd)
, " array length = " ++ (show $ V.length vec)]
| otherwise
= join
$ V.zipWith V.replicate
(V.convert $ U.lengthsSegd segd)
vec
replicates' :: PArray Int -> PArray a -> PArray a
replicates' reps arr
= replicates (U.lengthsToSegd $ V.convert $ reps) arr
append :: PArray a -> PArray a -> PArray a
append = (V.++)
appendl :: PArray (PArray a) -> PArray (PArray a) -> PArray (PArray a)
appendl = lift2 append
concat :: PArray (PArray a) -> PArray a
concat = join
concatl :: PArray (PArray (PArray a)) -> PArray (PArray a)
concatl = lift1 concat
unconcat :: PArray (PArray a) -> PArray b -> PArray (PArray b)
unconcat arr1 arr2
= nestUSegd (takeUSegd arr1) arr2
nestUSegd :: U.Segd -> PArray a -> PArray (PArray a)
nestUSegd segd vec
| U.elementsSegd segd == V.length vec
= V.zipWith
(\start len -> V.slice start len vec)
(V.convert $ U.indicesSegd segd)
(V.convert $ U.lengthsSegd segd)
| otherwise
= error $ unlines
[ "Data.Array.Parallel.PArray.nestSegd: number of elements defined by "
++ "segment descriptor and data array do not match"
, " length of segment desciptor = " ++ (show $ U.elementsSegd segd)
, " length of data array = " ++ (show $ V.length vec)]
length :: PArray a -> Int
length = V.length
lengthl :: PArray (PArray a) -> PArray Int
lengthl = lift1 length
index :: PArray a -> Int -> a
index = (V.!)
indexl :: PArray (PArray a) -> PArray Int -> PArray a
indexl = lift2 index
extract :: PArray a -> Int -> Int -> PArray a
extract vec start len
= V.slice start len vec
extracts :: Vector (PArray a) -> U.SSegd -> PArray a
extracts arrs ssegd
= join
$ V.zipWith3
(\src start len -> extract (arrs V.! src) start len)
(V.convert $ U.sourcesOfSSegd ssegd)
(V.convert $ U.startsOfSSegd ssegd)
(V.convert $ U.lengthsOfSSegd ssegd)
extracts'
:: Vector (PArray a)
-> PArray Int
-> PArray Int
-> PArray Int
-> PArray a
extracts' arrs sources starts lengths
= let segd = U.lengthsToSegd $ V.convert lengths
ssegd = U.mkSSegd
(V.convert $ starts)
(V.convert $ sources)
segd
in extracts arrs ssegd
slice :: Int -> Int -> PArray a -> PArray a
slice start len arr
= extract arr start len
slicel :: PArray Int -> PArray Int -> PArray (PArray a) -> PArray (PArray a)
slicel = lift3 slice
takeUSegd :: PArray (PArray a) -> U.Segd
takeUSegd vec
= U.lengthsToSegd
$ V.convert
$ V.map length vec
pack :: PArray a -> PArray Bool -> PArray a
pack xs bs
| V.length xs /= V.length bs
= die "pack" $ unlines
[ "array length mismatch"
, " data length = " ++ (show $ V.length xs)
, " flags length = " ++ (show $ V.length bs) ]
| otherwise
= V.ifilter (\i _ -> bs V.! i) xs
packl :: PArray (PArray a) -> PArray (PArray Bool) -> PArray (PArray a)
packl = lift2 pack
packByTag :: PArray a -> U.Array Tag -> Tag -> PArray a
packByTag xs tags tag
| V.length xs /= U.length tags
= die "packByTag" $ unlines
[ "array length mismatch"
, " data length = " ++ (show $ V.length xs)
, " flags length = " ++ (show $ U.length tags) ]
| otherwise
= V.ifilter (\i _ -> U.index (here "packByTag") tags i == tag) xs
combine2 :: U.Sel2 -> PArray a -> PArray a -> PArray a
combine2 tags vec1 vec2
= let go [] [] [] = []
go (0 : bs) (x : xs) ys = x : go bs xs ys
go (1 : bs) xs (y : ys) = y : go bs xs ys
go _ _ _ = error "Data.Array.Parallel.PArray.combine: length mismatch"
in V.fromList
$ go (V.toList $ V.convert $ U.tagsSel2 tags)
(V.toList vec1)
(V.toList vec2)
enumFromTo :: Int -> Int -> PArray Int
enumFromTo = V.enumFromTo
enumFromTol :: PArray Int -> PArray Int -> PArray (PArray Int)
enumFromTol = lift2 enumFromTo
zip :: PArray a -> PArray b -> PArray (a, b)
zip = V.zip
zipl :: PArray (PArray a) -> PArray (PArray b) -> PArray (PArray (a, b))
zipl = lift2 zip
unzip :: PArray (a, b) -> (PArray a, PArray b)
unzip = V.unzip
unzipl :: PArray (PArray (a, b)) -> PArray (PArray a, PArray b)
unzipl = lift1 unzip
fromVector :: Vector a -> PArray a
fromVector = id
toVector :: PArray a -> Vector a
toVector = id
fromList :: [a] -> PArray a
fromList = V.fromList
toList :: PArray a -> [a]
toList = V.toList
fromUArray :: U.Elt a => U.Array a -> PArray a
fromUArray = V.convert
toUArray :: U.Elt a => PArray a -> U.Array a
toUArray = V.convert
fromUArray2
:: (U.Elt a, U.Elt b)
=> U.Array (a, b) -> PArray (a, b)
fromUArray2 = V.convert