#include "fusion-phases.h"
module Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics (
lengthSU, singletonSU, replicateSU, replicateCU, (!:^),
flattenSU, (>:), segmentU, segmentArrU, concatSU, (^+:+^),
sliceIndexSU, extractIndexSU, indexedSU,
fstSU, sndSU, zipSU,
enumFromToSU, enumFromThenToSU,
toSU, fromSU,(+:+^)
) where
import Data.Array.Parallel.Base (
(:*:)(..))
import Data.Array.Parallel.Stream (
Step(..), Stream(..),SStream(..),(+++), (^+++^))
import Data.Array.Parallel.Unlifted.Sequential.Flat
import Data.Array.Parallel.Unlifted.Sequential.Segmented.Stream (streamSU,unstreamSU)
import Data.Array.Parallel.Unlifted.Sequential.Segmented.SUArr (
SUArr, lengthSU, (>:), flattenSU, segdSU, lengthsSU, indicesSU,
lengthsToUSegd, singletonUSegd, toUSegd)
import Debug.Trace
import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd (lengthsUSegd, indicesUSegd)
singletonSU :: UA e => UArr e -> SUArr e
singletonSU es = singletonUSegd (lengthU es) >: es
replicateSU :: UA e => UArr Int -> UArr e -> SUArr e
replicateSU ns es = lengthsToUSegd ns >: replicateEachU (sumU ns) ns es
replicateCU:: (UA e) => Int -> UArr e -> SUArr e
replicateCU n arr = segmentArrU (replicateU n rLen) $ repeatU n arr
where
rLen = lengthU arr
(!:^) :: (UA e) => SUArr e -> UArr Int -> UArr e
(!:^) sArr inds = bpermuteU (flattenSU sArr) newInds
where
xsLens = lengthsSU sArr
newInds = zipWithU (+) inds $ scanU (+) 0 xsLens
segmentU :: (UA e', UA e) => SUArr e' -> UArr e -> SUArr e
segmentU template arr = segdSU template >: arr
segmentArrU :: (UA e) => UArr Int -> UArr e -> SUArr e
segmentArrU lengths arr = (lengthsToUSegd lengths) >: arr
concatSU :: UA e => SUArr e -> UArr e
concatSU = flattenSU
indexSU :: UA e => (UArr e -> Int -> Int -> UArr e) -> SUArr e -> Int -> UArr e
indexSU copy sa i = copy (concatSU sa) (indicesSU sa !: i)
(lengthsSU sa !: i)
sliceIndexSU :: UA e => SUArr e -> Int -> UArr e
sliceIndexSU = indexSU sliceU
extractIndexSU :: UA e => SUArr e -> Int -> UArr e
extractIndexSU = indexSU extractU
indexedSU :: UA e => SUArr e -> SUArr (Int :*: e)
indexedSU xss = segdSU xss >: zipU is xs
where
xs = concatSU xss
is = enumFromToEachU (lengthU xs)
. zipU (replicateU (lengthSU xss) 0)
. mapU (subtract 1)
$ lengthsSU xss
infixr 5 ^+:+^
(^+:+^) :: UA a => SUArr a -> SUArr a -> SUArr a
xss ^+:+^ yss = toUSegd (zipU lens idxs)
>: unstreamU (streamSU xss ^+++^ streamSU yss)
where
lens = zipWithU (+) (lengthsSU xss) (lengthsSU yss)
idxs = zipWithU (+) (indicesSU xss) (indicesSU yss)
fstSU :: (UA a, UA b) => SUArr (a :*: b) -> SUArr a
fstSU sa = segdSU sa >: fstU (concatSU sa)
sndSU :: (UA a, UA b) => SUArr (a :*: b) -> SUArr b
sndSU sa = segdSU sa >: sndU (concatSU sa)
zipSU :: (UA a, UA b) => SUArr a -> SUArr b -> SUArr (a :*: b)
zipSU sa sb = segdSU sa >: zipU (concatSU sa) (concatSU sb)
enumFromToSU :: (Enum e, UA e) => UArr e -> UArr e -> SUArr e
enumFromToSU starts = enumFromThenToSU starts (mapU succ starts)
enumFromThenToSU :: (Enum e, UA e)
=> UArr e -> UArr e -> UArr e -> SUArr e
enumFromThenToSU starts nexts ends =
segd >: unstreamU (enumFromThenToEachS len
(streamU (zipU (zipU lens starts) nexts)))
where
lens = zipWith3U calcLen starts nexts ends
where
calcLen start next end =
abs (end' start' + delta) `div` (abs delta)
where
start' = fromEnum start
next' = fromEnum next
end' = fromEnum end
delta = next' start'
len = sumU lens
segd = lengthsToUSegd lens
enumFromThenToEachS :: Enum a => Int -> Stream (Int :*: a :*: a) -> Stream a
enumFromThenToEachS n (Stream next s _) =
Stream next' (0 :*: 0 :*: 0 :*: s) n
where
next' (0 :*: start :*: delta :*: s) =
case next s of
Done -> Done
Skip s' -> Skip (0 :*: start :*: delta :*: s')
Yield (len :*: i :*: k) s'
-> let start' = fromEnum i
in Skip (len :*: start' :*: fromEnum k start' :*: s')
next' (n :*: start :*: delta :*: s) =
Yield (toEnum start) (n1 :*: start+delta :*: delta :*: s)
(+:+^) :: UA e => SUArr e -> SUArr e -> SUArr e
a1 +:+^ a2 = unstreamSU $ SStream (segs1 +++ segs2) (vals1 +++ vals2)
where
(SStream segs1 vals1) = streamSU a1
(SStream segs2 vals2) = streamSU a2
toSU :: UA e => [[e]] -> SUArr e
toSU ls = let lens = toU $ map length ls
a = toU $ concat ls
in
lengthsToUSegd lens >: a
fromSU :: UA e => SUArr e -> [[e]]
fromSU sa = let a = concatSU sa
lens = fromU $ lengthsSU sa
starts = fromU $ indicesSU sa
in
[[a !: i | i <- [start .. start + len 1]]
| (start, len) <- zip starts lens]