module Data.Array.Repa.Operators.Reduction
( foldS, foldP
, foldAllS, foldAllP
, sumS, sumP
, sumAllS, sumAllP)
where
import Data.Array.Repa.Base
import Data.Array.Repa.Index
import Data.Array.Repa.Eval.Elt
import Data.Array.Repa.Repr.Unboxed
import Data.Array.Repa.Shape as S
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as M
import Prelude hiding (sum)
import qualified Data.Array.Repa.Eval.Reduction as E
import System.IO.Unsafe
import GHC.Exts
foldS :: (Shape sh, Elt a, Unbox a, Repr r a)
=> (a -> a -> a)
-> a
-> Array r (sh :. Int) a
-> Array U sh a
foldS f z arr
= let sh@(sz :. n') = extent arr
!(I# n) = n'
in unsafePerformIO
$ do mvec <- M.unsafeNew (S.size sz)
E.foldS mvec (\ix -> arr `unsafeIndex` fromIndex sh (I# ix)) f z n
!vec <- V.unsafeFreeze mvec
return $ fromUnboxed sz vec
foldP :: (Shape sh, Elt a, Unbox a, Repr r a)
=> (a -> a -> a)
-> a
-> Array r (sh :. Int) a
-> Array U sh a
foldP f z arr
= let sh@(sz :. n) = extent arr
in case rank sh of
1 -> let !vec = V.singleton $ foldAllP f z arr
in fromUnboxed sz vec
_ -> unsafePerformIO
$ do mvec <- M.unsafeNew (S.size sz)
E.foldP mvec (\ix -> arr `unsafeIndex` fromIndex sh ix) f z n
!vec <- V.unsafeFreeze mvec
return $ fromUnboxed sz vec
foldAllS :: (Shape sh, Elt a, Unbox a, Repr r a)
=> (a -> a -> a)
-> a
-> Array r sh a
-> a
foldAllS f z arr
= arr `deepSeqArray`
let !ex = extent arr
!(I# n) = size ex
in E.foldAllS
(\ix -> arr `unsafeIndex` fromIndex ex (I# ix))
f z n
foldAllP :: (Shape sh, Elt a, Unbox a, Repr r a)
=> (a -> a -> a)
-> a
-> Array r sh a
-> a
foldAllP f z arr
= let sh = extent arr
n = size sh
in unsafePerformIO
$ E.foldAllP (\ix -> arr `unsafeIndex` fromIndex sh ix) f z n
sumS :: (Shape sh, Num a, Elt a, Unbox a, Repr r a)
=> Array r (sh :. Int) a
-> Array U sh a
sumS = foldS (+) 0
sumP :: (Shape sh, Num a, Elt a, Unbox a, Repr r a)
=> Array r (sh :. Int) a
-> Array U sh a
sumP = foldP (+) 0
sumAllS :: (Shape sh, Elt a, Unbox a, Num a, Repr r a)
=> Array r sh a
-> a
sumAllS = foldAllS (+) 0
sumAllP :: (Shape sh, Elt a, Unbox a, Num a, Repr r a)
=> Array r sh a
-> a
sumAllP = foldAllP (+) 0