module Data.Array.Accelerate.Prelude (
zipWith3, zipWith4, zipWith5, zipWith6, zipWith7, zipWith8, zipWith9,
zip, zip3, zip4, zip5, zip6, zip7, zip8, zip9,
unzip, unzip3, unzip4, unzip5, unzip6, unzip7, unzip8, unzip9,
foldAll, fold1All,
all, any, and, or, sum, product, minimum, maximum,
prescanl, postscanl, prescanr, postscanr,
scanlSeg, scanl'Seg, scanl1Seg, prescanlSeg, postscanlSeg,
scanrSeg, scanr'Seg, scanr1Seg, prescanrSeg, postscanrSeg,
flatten,
fill, enumFromN, enumFromStepN,
(++),
filter,
scatter, scatterIf,
gather, gatherIf,
reverse, transpose,
init, tail, take, drop, slit,
(?|),
(?), caseof,
iterate,
sfoldl,
Lift(..), Unlift(..),
lift1, lift2, ilift1, ilift2,
fst, afst, snd, asnd, curry, uncurry,
index0, index1, unindex1, index2, unindex2,
the, null, length,
) where
import Data.Bits
import Data.Bool
import Prelude ((.), ($), (+), (), (*), const, subtract, id, min, max, Float,
Double, Char)
import qualified Prelude as P
import Data.Array.Accelerate.Array.Sugar hiding ((!), ignore, shape, size, intersect)
import Data.Array.Accelerate.Language
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Tuple
import Data.Array.Accelerate.Type
zipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d)
=> (Exp a -> Exp b -> Exp c -> Exp d)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
zipWith3 f as bs cs
= generate (shape as `intersect` shape bs `intersect` shape cs)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix))
zipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
zipWith4 f as bs cs ds
= generate (shape as `intersect` shape bs `intersect`
shape cs `intersect` shape ds)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix))
zipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
zipWith5 f as bs cs ds es
= generate (shape as `intersect` shape bs `intersect` shape cs
`intersect` shape ds `intersect` shape es)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix) (es ! ix))
zipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
zipWith6 f as bs cs ds es fs
= generate (shape as `intersect` shape bs `intersect` shape cs
`intersect` shape ds `intersect` shape es
`intersect` shape fs)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix) (es ! ix) (fs ! ix))
zipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh h)
zipWith7 f as bs cs ds es fs gs
= generate (shape as `intersect` shape bs `intersect` shape cs
`intersect` shape ds `intersect` shape es
`intersect` shape fs `intersect` shape gs)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix) (es ! ix) (fs ! ix) (gs ! ix))
zipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh h)
-> Acc (Array sh i)
zipWith8 f as bs cs ds es fs gs hs
= generate (shape as `intersect` shape bs `intersect` shape cs
`intersect` shape ds `intersect` shape es
`intersect` shape fs `intersect` shape gs
`intersect` shape hs)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix) (es ! ix) (fs ! ix) (gs ! ix) (hs ! ix))
zipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)
=> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j)
-> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh h)
-> Acc (Array sh i)
-> Acc (Array sh j)
zipWith9 f as bs cs ds es fs gs hs is
= generate (shape as `intersect` shape bs `intersect` shape cs
`intersect` shape ds `intersect` shape es
`intersect` shape fs `intersect` shape gs
`intersect` shape hs `intersect` shape is)
(\ix -> f (as ! ix) (bs ! ix) (cs ! ix) (ds ! ix) (es ! ix) (fs ! ix) (gs ! ix) (hs ! ix) (is ! ix))
zip :: (Shape sh, Elt a, Elt b)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh (a, b))
zip = zipWith (curry lift)
zip3 :: (Shape sh, Elt a, Elt b, Elt c)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh (a, b, c))
zip3 = zipWith3 (\a b c -> lift (a,b,c))
zip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh (a, b, c, d))
zip4 = zipWith4 (\a b c d -> lift (a,b,c,d))
zip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh (a, b, c, d, e))
zip5 = zipWith5 (\a b c d e -> lift (a,b,c,d,e))
zip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh (a, b, c, d, e, f))
zip6 = zipWith6 (\a b c d e f -> lift (a,b,c,d,e,f))
zip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh (a, b, c, d, e, f, g))
zip7 = zipWith7 (\a b c d e f g -> lift (a,b,c,d,e,f,g))
zip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh h)
-> Acc (Array sh (a, b, c, d, e, f, g, h))
zip8 = zipWith8 (\a b c d e f g h -> lift (a,b,c,d,e,f,g,h))
zip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)
=> Acc (Array sh a)
-> Acc (Array sh b)
-> Acc (Array sh c)
-> Acc (Array sh d)
-> Acc (Array sh e)
-> Acc (Array sh f)
-> Acc (Array sh g)
-> Acc (Array sh h)
-> Acc (Array sh i)
-> Acc (Array sh (a, b, c, d, e, f, g, h, i))
zip9 = zipWith9 (\a b c d e f g h i -> lift (a,b,c,d,e,f,g,h,i))
unzip :: (Shape sh, Elt a, Elt b)
=> Acc (Array sh (a, b))
-> (Acc (Array sh a), Acc (Array sh b))
unzip arr = (map fst arr, map snd arr)
unzip3 :: (Shape sh, Elt a, Elt b, Elt c)
=> Acc (Array sh (a, b, c))
-> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c))
unzip3 xs = (map get1 xs, map get2 xs, map get3 xs)
where
get1 x = let (a,_,_) = untup3 x in a
get2 x = let (_,b,_) = untup3 x in b
get3 x = let (_,_,c) = untup3 x in c
unzip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d)
=> Acc (Array sh (a, b, c, d))
-> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d))
unzip4 xs = (map get1 xs, map get2 xs, map get3 xs, map get4 xs)
where
get1 x = let (a,_,_,_) = untup4 x in a
get2 x = let (_,b,_,_) = untup4 x in b
get3 x = let (_,_,c,_) = untup4 x in c
get4 x = let (_,_,_,d) = untup4 x in d
unzip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)
=> Acc (Array sh (a, b, c, d, e))
-> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e))
unzip5 xs = (map get1 xs, map get2 xs, map get3 xs, map get4 xs, map get5 xs)
where
get1 x = let (a,_,_,_,_) = untup5 x in a
get2 x = let (_,b,_,_,_) = untup5 x in b
get3 x = let (_,_,c,_,_) = untup5 x in c
get4 x = let (_,_,_,d,_) = untup5 x in d
get5 x = let (_,_,_,_,e) = untup5 x in e
unzip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)
=> Acc (Array sh (a, b, c, d, e, f))
-> ( Acc (Array sh a), Acc (Array sh b), Acc (Array sh c)
, Acc (Array sh d), Acc (Array sh e), Acc (Array sh f))
unzip6 xs = (map get1 xs, map get2 xs, map get3 xs, map get4 xs, map get5 xs, map get6 xs)
where
get1 x = let (a,_,_,_,_,_) = untup6 x in a
get2 x = let (_,b,_,_,_,_) = untup6 x in b
get3 x = let (_,_,c,_,_,_) = untup6 x in c
get4 x = let (_,_,_,d,_,_) = untup6 x in d
get5 x = let (_,_,_,_,e,_) = untup6 x in e
get6 x = let (_,_,_,_,_,f) = untup6 x in f
unzip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)
=> Acc (Array sh (a, b, c, d, e, f, g))
-> ( Acc (Array sh a), Acc (Array sh b), Acc (Array sh c)
, Acc (Array sh d), Acc (Array sh e), Acc (Array sh f)
, Acc (Array sh g))
unzip7 xs = ( map get1 xs, map get2 xs, map get3 xs
, map get4 xs, map get5 xs, map get6 xs
, map get7 xs )
where
get1 x = let (a,_,_,_,_,_,_) = untup7 x in a
get2 x = let (_,b,_,_,_,_,_) = untup7 x in b
get3 x = let (_,_,c,_,_,_,_) = untup7 x in c
get4 x = let (_,_,_,d,_,_,_) = untup7 x in d
get5 x = let (_,_,_,_,e,_,_) = untup7 x in e
get6 x = let (_,_,_,_,_,f,_) = untup7 x in f
get7 x = let (_,_,_,_,_,_,g) = untup7 x in g
unzip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)
=> Acc (Array sh (a, b, c, d, e, f, g, h))
-> ( Acc (Array sh a), Acc (Array sh b), Acc (Array sh c)
, Acc (Array sh d), Acc (Array sh e), Acc (Array sh f)
, Acc (Array sh g), Acc (Array sh h) )
unzip8 xs = ( map get1 xs, map get2 xs, map get3 xs
, map get4 xs, map get5 xs, map get6 xs
, map get7 xs, map get8 xs )
where
get1 x = let (a,_,_,_,_,_,_,_) = untup8 x in a
get2 x = let (_,b,_,_,_,_,_,_) = untup8 x in b
get3 x = let (_,_,c,_,_,_,_,_) = untup8 x in c
get4 x = let (_,_,_,d,_,_,_,_) = untup8 x in d
get5 x = let (_,_,_,_,e,_,_,_) = untup8 x in e
get6 x = let (_,_,_,_,_,f,_,_) = untup8 x in f
get7 x = let (_,_,_,_,_,_,g,_) = untup8 x in g
get8 x = let (_,_,_,_,_,_,_,h) = untup8 x in h
unzip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)
=> Acc (Array sh (a, b, c, d, e, f, g, h, i))
-> ( Acc (Array sh a), Acc (Array sh b), Acc (Array sh c)
, Acc (Array sh d), Acc (Array sh e), Acc (Array sh f)
, Acc (Array sh g), Acc (Array sh h), Acc (Array sh i))
unzip9 xs = ( map get1 xs, map get2 xs, map get3 xs
, map get4 xs, map get5 xs, map get6 xs
, map get7 xs, map get8 xs, map get9 xs )
where
get1 x = let (a,_,_,_,_,_,_,_,_) = untup9 x in a
get2 x = let (_,b,_,_,_,_,_,_,_) = untup9 x in b
get3 x = let (_,_,c,_,_,_,_,_,_) = untup9 x in c
get4 x = let (_,_,_,d,_,_,_,_,_) = untup9 x in d
get5 x = let (_,_,_,_,e,_,_,_,_) = untup9 x in e
get6 x = let (_,_,_,_,_,f,_,_,_) = untup9 x in f
get7 x = let (_,_,_,_,_,_,g,_,_) = untup9 x in g
get8 x = let (_,_,_,_,_,_,_,h,_) = untup9 x in h
get9 x = let (_,_,_,_,_,_,_,_,i) = untup9 x in i
foldAll :: (Shape sh, Elt a)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Array sh a)
-> Acc (Scalar a)
foldAll f e arr = fold f e (flatten arr)
fold1All :: (Shape sh, Elt a)
=> (Exp a -> Exp a -> Exp a)
-> Acc (Array sh a)
-> Acc (Scalar a)
fold1All f arr = fold1 f (flatten arr)
all :: (Shape sh, Elt e)
=> (Exp e -> Exp Bool)
-> Acc (Array sh e)
-> Acc (Scalar Bool)
all f = and . map f
any :: (Shape sh, Elt e)
=> (Exp e -> Exp Bool)
-> Acc (Array sh e)
-> Acc (Scalar Bool)
any f = or . map f
and :: Shape sh
=> Acc (Array sh Bool)
-> Acc (Scalar Bool)
and = foldAll (&&*) (constant True)
or :: Shape sh
=> Acc (Array sh Bool)
-> Acc (Scalar Bool)
or = foldAll (||*) (constant False)
sum :: (Shape sh, Elt e, IsNum e)
=> Acc (Array sh e)
-> Acc (Scalar e)
sum = foldAll (+) 0
product :: (Shape sh, Elt e, IsNum e)
=> Acc (Array sh e)
-> Acc (Scalar e)
product = foldAll (*) 1
minimum :: (Shape sh, Elt e, IsScalar e)
=> Acc (Array sh e)
-> Acc (Scalar e)
minimum = fold1All min
maximum :: (Shape sh, Elt e, IsScalar e)
=> Acc (Array sh e)
-> Acc (Scalar e)
maximum = fold1All max
prescanl :: Elt a
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Vector a)
prescanl f e = P.fst . scanl' f e
postscanl :: Elt a
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Vector a)
postscanl f e = map (e `f`) . scanl1 f
prescanr :: Elt a
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Vector a)
prescanr f e = P.fst . scanr' f e
postscanr :: Elt a
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Vector a)
postscanr f e = map (`f` e) . scanr1 f
scanlSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
scanlSeg f z vec seg = scanl1Seg f vec' seg'
where
seg' = map (+1) seg
vec' = permute const
(fill (index1 $ size vec + size seg) z)
(\ix -> index1' $ unindex1' ix + inc ! ix)
vec
flags = mkHeadFlags seg
inc = scanl1 (+) flags
scanl'Seg :: forall a i. (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a, Vector a)
scanl'Seg f z vec seg = result
where
result = lift (body, sums)
vec' = scanlSeg f z vec seg
seg' = map (+1) seg
tails = zipWith (+) seg . P.fst $ scanl' (+) 0 seg'
sums = backpermute (shape seg) (\ix -> index1' $ tails ! ix) vec'
offset = scanl1 (+) seg
inc = scanl1 (+)
$ permute (+) (fill (index1 $ size vec + 1) 0)
(\ix -> index1' $ offset ! ix)
(fill (shape seg) (1 :: Exp i))
body = backpermute (shape vec)
(\ix -> index1' $ unindex1' ix + inc ! ix)
vec'
scanl1Seg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
scanl1Seg f vec seg
= P.snd
. unzip
. scanl1 (segmented f)
$ zip (mkHeadFlags seg) vec
prescanlSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
prescanlSeg f e vec seg
= P.fst
. unatup2
$ scanl'Seg f e vec seg
postscanlSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
postscanlSeg f e vec seg
= map (f e)
$ scanl1Seg f vec seg
scanrSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
scanrSeg f z vec seg = scanr1Seg f vec' seg'
where
inc = scanl1 (+) (mkHeadFlags seg)
seg' = map (+1) seg
vec' = permute const
(fill (index1 $ size vec + size seg) z)
(\ix -> index1' $ unindex1' ix + inc ! ix 1)
vec
scanr'Seg :: forall a i. (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a, Vector a)
scanr'Seg f z vec seg = result
where
result = lift (body, sums)
vec' = scanrSeg f z vec seg
seg' = map (+1) seg
heads = P.fst $ scanl' (+) 0 seg'
sums = backpermute (shape seg) (\ix -> index1' $ heads ! ix) vec'
inc = scanl1 (+) $ mkHeadFlags seg
body = backpermute (shape vec)
(\ix -> index1' $ unindex1' ix + inc ! ix)
vec'
scanr1Seg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
scanr1Seg f vec seg
= P.snd
. unzip
. scanr1 (segmented f)
$ zip (mkTailFlags seg) vec
prescanrSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
prescanrSeg f e vec seg
= P.fst
. unatup2
$ scanr'Seg f e vec seg
postscanrSeg :: (Elt a, Elt i, IsIntegral i)
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Segments i)
-> Acc (Vector a)
postscanrSeg f e vec seg
= map (f e)
$ scanr1Seg f vec seg
mkHeadFlags :: (Elt i, IsIntegral i) => Acc (Segments i) -> Acc (Segments i)
mkHeadFlags seg
= init
$ permute (+) zeros (\ix -> index1' (offset ! ix)) ones
where
(offset, len) = scanl' (+) 0 seg
zeros = fill (index1' $ the len + 1) 0
ones = fill (index1 $ size offset) 1
mkTailFlags :: (Elt i, IsIntegral i) => Acc (Segments i) -> Acc (Segments i)
mkTailFlags seg
= init
$ permute (+) zeros (\ix -> index1' (the len 1 offset ! ix)) ones
where
(offset, len) = scanr' (+) 0 seg
zeros = fill (index1' $ the len + 1) 0
ones = fill (index1 $ size offset) 1
segmented :: (Elt e, Elt i, IsIntegral i)
=> (Exp e -> Exp e -> Exp e)
-> Exp (i, e) -> Exp (i, e) -> Exp (i, e)
segmented f a b =
let (aF, aV) = unlift a
(bF, bV) = unlift b
in
lift (aF .|. bF, bF /=* 0 ? (bV, f aV bV))
index1' :: (Elt i, IsIntegral i) => Exp i -> Exp DIM1
index1' i = lift (Z :. fromIntegral i)
unindex1' :: (Elt i, IsIntegral i) => Exp DIM1 -> Exp i
unindex1' ix = let Z :. i = unlift ix in fromIntegral i
flatten :: (Shape ix, Elt a) => Acc (Array ix a) -> Acc (Vector a)
flatten a = reshape (index1 $ size a) a
fill :: (Shape sh, Elt e) => Exp sh -> Exp e -> Acc (Array sh e)
fill sh c = generate sh (const c)
enumFromN :: (Shape sh, Elt e, IsNum e) => Exp sh -> Exp e -> Acc (Array sh e)
enumFromN sh x = enumFromStepN sh x 1
enumFromStepN :: (Shape sh, Elt e, IsNum e)
=> Exp sh
-> Exp e
-> Exp e
-> Acc (Array sh e)
enumFromStepN sh x y
= reshape sh
$ generate (index1 $ shapeSize sh)
(\ix -> (fromIntegral (unindex1 ix :: Exp Int) * y) + x)
infixr 5 ++
(++) :: forall sh e. (Slice sh, Shape sh, Elt e)
=> Acc (Array (sh :. Int) e)
-> Acc (Array (sh :. Int) e)
-> Acc (Array (sh :. Int) e)
(++) xs ys
= let sh1 :. n = unlift (shape xs) :: Exp sh :. Exp Int
sh2 :. m = unlift (shape ys) :: Exp sh :. Exp Int
in
generate (lift (intersect sh1 sh2 :. n + m))
(\ix -> let sh :. i = unlift ix :: Exp sh :. Exp Int
in i <* n ? ( xs ! ix, ys ! lift (sh :. in)) )
filter :: Elt a
=> (Exp a -> Exp Bool)
-> Acc (Vector a)
-> Acc (Vector a)
filter p arr
= let flags = map (boolToInt . p) arr
(targetIdx, len) = scanl' (+) 0 flags
arr' = backpermute (index1 $ the len) id arr
in
permute const arr' (\ix -> flags!ix ==* 0 ? (ignore, index1 $ targetIdx!ix)) arr
gather :: Elt e
=> Acc (Vector Int)
-> Acc (Vector e)
-> Acc (Vector e)
gather from input = backpermute (shape from) bpF input
where
bpF ix = index1 (from ! ix)
gatherIf :: (Elt e, Elt e')
=> Acc (Vector Int)
-> Acc (Vector e)
-> (Exp e -> Exp Bool)
-> Acc (Vector e')
-> Acc (Vector e')
-> Acc (Vector e')
gatherIf from maskV pred defaults input = zipWith zf pf gatheredV
where
zf p g = p ? (unlift g)
gatheredV = zip (gather from input) defaults
pf = map pred maskV
scatter :: Elt e
=> Acc (Vector Int)
-> Acc (Vector e)
-> Acc (Vector e)
-> Acc (Vector e)
scatter to defaults input = permute const defaults pf input'
where
pf ix = index1 (to ! ix)
input' = backpermute (shape to `intersect` shape input) id input
scatterIf :: (Elt e, Elt e')
=> Acc (Vector Int)
-> Acc (Vector e)
-> (Exp e -> Exp Bool)
-> Acc (Vector e')
-> Acc (Vector e')
-> Acc (Vector e')
scatterIf to maskV pred defaults input = permute const defaults pf input'
where
pf ix = pred (maskV ! ix) ? ( index1 (to ! ix), ignore )
input' = backpermute (shape to `intersect` shape input) id input
reverse :: Elt e => Acc (Vector e) -> Acc (Vector e)
reverse xs =
let len = unindex1 (shape xs)
pf i = len i 1
in backpermute (shape xs) (ilift1 pf) xs
transpose :: Elt e => Acc (Array DIM2 e) -> Acc (Array DIM2 e)
transpose mat =
let swap = lift1 $ \(Z:.x:.y) -> Z:.y:.x :: Z:.Exp Int:.Exp Int
in backpermute (swap $ shape mat) swap mat
take :: Elt e => Exp Int -> Acc (Vector e) -> Acc (Vector e)
take n =
let n' = the (unit n)
in backpermute (index1 n') id
drop :: Elt e => Exp Int -> Acc (Vector e) -> Acc (Vector e)
drop n arr =
let n' = the (unit n)
in backpermute (ilift1 (subtract n') (shape arr)) (ilift1 (+ n')) arr
init :: Elt e => Acc (Vector e) -> Acc (Vector e)
init arr = backpermute (ilift1 (subtract 1) (shape arr)) id arr
tail :: Elt e => Acc (Vector e) -> Acc (Vector e)
tail arr = backpermute (ilift1 (subtract 1) (shape arr)) (ilift1 (+1)) arr
slit :: Elt e => Exp Int -> Exp Int -> Acc (Vector e) -> Acc (Vector e)
slit i n =
let i' = the (unit i)
n' = the (unit n)
in backpermute (index1 n') (ilift1 (+ i'))
infix 0 ?|
(?|) :: (Arrays a) => Exp Bool -> (Acc a, Acc a) -> Acc a
c ?| (t, e) = acond c t e
infix 0 ?
(?) :: Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t
c ? (t, e) = cond c t e
caseof :: (Elt a, Elt b)
=> Exp a
-> [(Exp a -> Exp Bool, Exp b)]
-> Exp b
-> Exp b
caseof _ [] e = e
caseof x ((p,b):l) e = cond (p x) b (caseof x l e)
iterate :: forall a. Elt a
=> Exp Int
-> (Exp a -> Exp a)
-> Exp a
-> Exp a
iterate n f z
= let step :: (Exp Int, Exp a) -> (Exp Int, Exp a)
step (i, acc) = ( i+1, f acc )
in
snd $ while (\v -> fst v <* n) (lift1 step) (lift (constant 0, z))
sfoldl :: forall sh a b. (Shape sh, Slice sh, Elt a, Elt b)
=> (Exp a -> Exp b -> Exp a)
-> Exp a
-> Exp sh
-> Acc (Array (sh :. Int) b)
-> Exp a
sfoldl f z ix xs
= let step :: (Exp Int, Exp a) -> (Exp Int, Exp a)
step (i, acc) = ( i+1, acc `f` (xs ! lift (ix :. i)) )
(_ :. n) = unlift (shape xs) :: Exp sh :. Exp Int
in
snd $ while (\v -> fst v <* n) (lift1 step) (lift (constant 0, z))
class Lift c e where
type Plain e
lift :: e -> c (Plain e)
class Lift c e => Unlift c e where
unlift :: c (Plain e) -> e
instance Lift Exp () where
type Plain () = ()
lift _ = Exp $ Tuple NilTup
instance Unlift Exp () where
unlift _ = ()
instance Lift Exp Z where
type Plain Z = Z
lift _ = Exp $ IndexNil
instance Unlift Exp Z where
unlift _ = Z
instance (Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. Int) where
type Plain (ix :. Int) = Plain ix :. Int
lift (ix:.i) = Exp $ IndexCons (lift ix) (Exp $ Const i)
instance (Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. All) where
type Plain (ix :. All) = Plain ix :. All
lift (ix:.i) = Exp $ IndexCons (lift ix) (Exp $ Const i)
instance (Elt e, Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. Exp e) where
type Plain (ix :. Exp e) = Plain ix :. e
lift (ix:.i) = Exp $ IndexCons (lift ix) i
instance (Elt e, Slice (Plain ix), Unlift Exp ix) => Unlift Exp (ix :. Exp e) where
unlift e = unlift (Exp $ IndexTail e) :. Exp (IndexHead e)
instance (Elt e, Slice ix) => Unlift Exp (Exp ix :. Exp e) where
unlift e = (Exp $ IndexTail e) :. Exp (IndexHead e)
instance Shape sh => Lift Exp (Any sh) where
type Plain (Any sh) = Any sh
lift Any = Exp $ IndexAny
instance Lift Exp Int where
type Plain Int = Int
lift = Exp . Const
instance Lift Exp Int8 where
type Plain Int8 = Int8
lift = Exp . Const
instance Lift Exp Int16 where
type Plain Int16 = Int16
lift = Exp . Const
instance Lift Exp Int32 where
type Plain Int32 = Int32
lift = Exp . Const
instance Lift Exp Int64 where
type Plain Int64 = Int64
lift = Exp . Const
instance Lift Exp Word where
type Plain Word = Word
lift = Exp . Const
instance Lift Exp Word8 where
type Plain Word8 = Word8
lift = Exp . Const
instance Lift Exp Word16 where
type Plain Word16 = Word16
lift = Exp . Const
instance Lift Exp Word32 where
type Plain Word32 = Word32
lift = Exp . Const
instance Lift Exp Word64 where
type Plain Word64 = Word64
lift = Exp . Const
instance Lift Exp CShort where
type Plain CShort = CShort
lift = Exp . Const
instance Lift Exp CUShort where
type Plain CUShort = CUShort
lift = Exp . Const
instance Lift Exp CInt where
type Plain CInt = CInt
lift = Exp . Const
instance Lift Exp CUInt where
type Plain CUInt = CUInt
lift = Exp . Const
instance Lift Exp CLong where
type Plain CLong = CLong
lift = Exp . Const
instance Lift Exp CULong where
type Plain CULong = CULong
lift = Exp . Const
instance Lift Exp CLLong where
type Plain CLLong = CLLong
lift = Exp . Const
instance Lift Exp CULLong where
type Plain CULLong = CULLong
lift = Exp . Const
instance Lift Exp Float where
type Plain Float = Float
lift = Exp . Const
instance Lift Exp Double where
type Plain Double = Double
lift = Exp . Const
instance Lift Exp CFloat where
type Plain CFloat = CFloat
lift = Exp . Const
instance Lift Exp CDouble where
type Plain CDouble = CDouble
lift = Exp . Const
instance Lift Exp Bool where
type Plain Bool = Bool
lift = Exp . Const
instance Lift Exp Char where
type Plain Char = Char
lift = Exp . Const
instance Lift Exp CChar where
type Plain CChar = CChar
lift = Exp . Const
instance Lift Exp CSChar where
type Plain CSChar = CSChar
lift = Exp . Const
instance Lift Exp CUChar where
type Plain CUChar = CUChar
lift = Exp . Const
instance (Lift Exp a, Lift Exp b, Elt (Plain a), Elt (Plain b)) => Lift Exp (a, b) where
type Plain (a, b) = (Plain a, Plain b)
lift (x, y) = tup2 (lift x, lift y)
instance (Elt a, Elt b) => Unlift Exp (Exp a, Exp b) where
unlift = untup2
instance (Lift Exp a, Lift Exp b, Lift Exp c,
Elt (Plain a), Elt (Plain b), Elt (Plain c))
=> Lift Exp (a, b, c) where
type Plain (a, b, c) = (Plain a, Plain b, Plain c)
lift (x, y, z) = tup3 (lift x, lift y, lift z)
instance (Elt a, Elt b, Elt c) => Unlift Exp (Exp a, Exp b, Exp c) where
unlift = untup3
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d))
=> Lift Exp (a, b, c, d) where
type Plain (a, b, c, d) = (Plain a, Plain b, Plain c, Plain d)
lift (x, y, z, u) = tup4 (lift x, lift y, lift z, lift u)
instance (Elt a, Elt b, Elt c, Elt d) => Unlift Exp (Exp a, Exp b, Exp c, Exp d) where
unlift = untup4
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d, Lift Exp e,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e))
=> Lift Exp (a, b, c, d, e) where
type Plain (a, b, c, d, e) = (Plain a, Plain b, Plain c, Plain d, Plain e)
lift (x, y, z, u, v) = tup5 (lift x, lift y, lift z, lift u, lift v)
instance (Elt a, Elt b, Elt c, Elt d, Elt e)
=> Unlift Exp (Exp a, Exp b, Exp c, Exp d, Exp e) where
unlift = untup5
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d, Lift Exp e, Lift Exp f,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f))
=> Lift Exp (a, b, c, d, e, f) where
type Plain (a, b, c, d, e, f) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f)
lift (x, y, z, u, v, w) = tup6 (lift x, lift y, lift z, lift u, lift v, lift w)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)
=> Unlift Exp (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f) where
unlift = untup6
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d, Lift Exp e, Lift Exp f, Lift Exp g,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f),
Elt (Plain g))
=> Lift Exp (a, b, c, d, e, f, g) where
type Plain (a, b, c, d, e, f, g) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g)
lift (x, y, z, u, v, w, r) = tup7 (lift x, lift y, lift z, lift u, lift v, lift w, lift r)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)
=> Unlift Exp (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g) where
unlift = untup7
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d, Lift Exp e, Lift Exp f, Lift Exp g, Lift Exp h,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f),
Elt (Plain g), Elt (Plain h))
=> Lift Exp (a, b, c, d, e, f, g, h) where
type Plain (a, b, c, d, e, f, g, h)
= (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h)
lift (x, y, z, u, v, w, r, s)
= tup8 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)
=> Unlift Exp (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h) where
unlift = untup8
instance (Lift Exp a, Lift Exp b, Lift Exp c, Lift Exp d, Lift Exp e,
Lift Exp f, Lift Exp g, Lift Exp h, Lift Exp i,
Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e),
Elt (Plain f), Elt (Plain g), Elt (Plain h), Elt (Plain i))
=> Lift Exp (a, b, c, d, e, f, g, h, i) where
type Plain (a, b, c, d, e, f, g, h, i)
= (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h, Plain i)
lift (x, y, z, u, v, w, r, s, t)
= tup9 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s, lift t)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)
=> Unlift Exp (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i) where
unlift = untup9
instance Lift Exp (Exp e) where
type Plain (Exp e) = e
lift = id
instance Lift Acc (Acc a) where
type Plain (Acc a) = a
lift = id
instance (Shape sh, Elt e) => Lift Acc (Array sh e) where
type Plain (Array sh e) = Array sh e
lift = Acc . Use
instance (Lift Acc a, Lift Acc b, Arrays (Plain a), Arrays (Plain b)) => Lift Acc (a, b) where
type Plain (a, b) = (Plain a, Plain b)
lift (x, y) = atup2 (lift x, lift y)
instance (Arrays a, Arrays b) => Unlift Acc (Acc a, Acc b) where
unlift = unatup2
instance (Lift Acc a, Lift Acc b, Lift Acc c,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c))
=> Lift Acc (a, b, c) where
type Plain (a, b, c) = (Plain a, Plain b, Plain c)
lift (x, y, z) = atup3 (lift x, lift y, lift z)
instance (Arrays a, Arrays b, Arrays c) => Unlift Acc (Acc a, Acc b, Acc c) where
unlift = unatup3
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d))
=> Lift Acc (a, b, c, d) where
type Plain (a, b, c, d) = (Plain a, Plain b, Plain c, Plain d)
lift (x, y, z, u) = atup4 (lift x, lift y, lift z, lift u)
instance (Arrays a, Arrays b, Arrays c, Arrays d) => Unlift Acc (Acc a, Acc b, Acc c, Acc d) where
unlift = unatup4
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d, Lift Acc e,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d), Arrays (Plain e))
=> Lift Acc (a, b, c, d, e) where
type Plain (a, b, c, d, e) = (Plain a, Plain b, Plain c, Plain d, Plain e)
lift (x, y, z, u, v) = atup5 (lift x, lift y, lift z, lift u, lift v)
instance (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)
=> Unlift Acc (Acc a, Acc b, Acc c, Acc d, Acc e) where
unlift = unatup5
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d, Lift Acc e, Lift Acc f,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d), Arrays (Plain e), Arrays (Plain f))
=> Lift Acc (a, b, c, d, e, f) where
type Plain (a, b, c, d, e, f) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f)
lift (x, y, z, u, v, w) = atup6 (lift x, lift y, lift z, lift u, lift v, lift w)
instance (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)
=> Unlift Acc (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f) where
unlift = unatup6
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d, Lift Acc e, Lift Acc f, Lift Acc g,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d), Arrays (Plain e), Arrays (Plain f),
Arrays (Plain g))
=> Lift Acc (a, b, c, d, e, f, g) where
type Plain (a, b, c, d, e, f, g) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g)
lift (x, y, z, u, v, w, r) = atup7 (lift x, lift y, lift z, lift u, lift v, lift w, lift r)
instance (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)
=> Unlift Acc (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g) where
unlift = unatup7
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d, Lift Acc e, Lift Acc f, Lift Acc g, Lift Acc h,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d), Arrays (Plain e), Arrays (Plain f),
Arrays (Plain g), Arrays (Plain h))
=> Lift Acc (a, b, c, d, e, f, g, h) where
type Plain (a, b, c, d, e, f, g, h)
= (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h)
lift (x, y, z, u, v, w, r, s)
= atup8 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s)
instance (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)
=> Unlift Acc (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h) where
unlift = unatup8
instance (Lift Acc a, Lift Acc b, Lift Acc c, Lift Acc d, Lift Acc e,
Lift Acc f, Lift Acc g, Lift Acc h, Lift Acc i,
Arrays (Plain a), Arrays (Plain b), Arrays (Plain c), Arrays (Plain d), Arrays (Plain e),
Arrays (Plain f), Arrays (Plain g), Arrays (Plain h), Arrays (Plain i))
=> Lift Acc (a, b, c, d, e, f, g, h, i) where
type Plain (a, b, c, d, e, f, g, h, i)
= (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h, Plain i)
lift (x, y, z, u, v, w, r, s, t)
= atup9 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s, lift t)
instance (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)
=> Unlift Acc (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i) where
unlift = unatup9
lift1 :: (Unlift Exp e1, Lift Exp e2)
=> (e1 -> e2)
-> Exp (Plain e1)
-> Exp (Plain e2)
lift1 f = lift . f . unlift
lift2 :: (Unlift Exp e1, Unlift Exp e2, Lift Exp e3)
=> (e1 -> e2 -> e3)
-> Exp (Plain e1)
-> Exp (Plain e2)
-> Exp (Plain e3)
lift2 f x y = lift $ f (unlift x) (unlift y)
ilift1 :: (Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1
ilift1 f = lift1 (\(Z:.i) -> Z :. f i)
ilift2 :: (Exp Int -> Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1 -> Exp DIM1
ilift2 f = lift2 (\(Z:.i) (Z:.j) -> Z :. f i j)
fst :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp a
fst e = let (x, _::Exp b) = unlift e in x
afst :: forall a b. (Arrays a, Arrays b) => Acc (a, b) -> Acc a
afst a = let (x, _::Acc b) = unlift a in x
snd :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp b
snd e = let (_:: Exp a, y) = unlift e in y
asnd :: forall a b. (Arrays a, Arrays b) => Acc (a, b) -> Acc b
asnd a = let (_::Acc a, y) = unlift a in y
curry :: Lift f (f a, f b) => (f (Plain (f a), Plain (f b)) -> f c) -> f a -> f b -> f c
curry f x y = f (lift (x, y))
uncurry :: Unlift f (f a, f b) => (f a -> f b -> f c) -> f (Plain (f a), Plain (f b)) -> f c
uncurry f t = let (x, y) = unlift t in f x y
index0 :: Exp Z
index0 = lift Z
index1 :: Elt i => Exp i -> Exp (Z :. i)
index1 i = lift (Z :. i)
unindex1 :: Elt i => Exp (Z :. i) -> Exp i
unindex1 ix = let Z :. i = unlift ix in i
index2 :: (Elt i, Slice (Z :. i))
=> Exp i
-> Exp i
-> Exp (Z :. i :. i)
index2 i j = lift (Z :. i :. j)
unindex2 :: forall i. (Elt i, Slice (Z :. i))
=> Exp (Z :. i :. i)
-> Exp (i, i)
unindex2 ix
= let Z :. i :. j = unlift ix :: Z :. Exp i :. Exp i
in lift (i, j)
the :: Elt e => Acc (Scalar e) -> Exp e
the = (!index0)
null :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp Bool
null arr = size arr ==* 0
length :: Elt e => Acc (Vector e) -> Exp Int
length = unindex1 . shape