Я разработал кумулятивную функцию суммы, как определено ниже в библиотеке Haskell Repa. Тем не менее, я столкнулся с проблемой при объединении этой функции с транспозицией. Все 3 из следующих операций занимают второе место:
cumsum $ cumsum $ cumsum x
transpose $ transpose $ transpose x
transpose $ cumsum x
Однако, если я пишу:
cumsum $ transpose x
производительность ухудшается ужасно. В то время как каждая отдельная операция в изоляции занимает значительно меньше секунды на изображении 1920x1080, при объединении они теперь занимают 30 + секунд...
Любые идеи о том, что может быть причиной этого? Моя кишка говорит мне, что это имеет какое-то отношение к задержанным массивам, а не к форсированию в нужное время и т.д. Но у меня недостаточно опыта, чтобы проследить это еще довольно давно.
{-# LANGUAGE TypeOperators, FlexibleContexts, TypeFamilies #-}
import Data.Array.Repa as Repa
{-# INLINE indexSlice #-}
indexSlice :: (Shape sh, Elt a) => Int -> Array (sh :. Int) a -> (sh :. Int) -> a
indexSlice from arr (z :. ix) = arr `unsafeIndex` (z :. (ix + from))
{-# INLINE sliceRange #-}
sliceRange :: (Slice sh, Shape sh, Elt a) => Int -> Int -> Array (sh :. Int) a -> Array (sh :. Int) a
sliceRange from to arr = fromFunction (z :. (to - from + 1)) $ indexSlice from arr
where (z :. _) = extent arr
{-# INLINE cumsum' #-}
cumsum' :: (Slice (SliceShape sh), Slice sh, Shape (FullShape sh), Shape (SliceShape sh), Elt a, Num a) =>
Array (FullShape sh :. Int) a -> t -> (sh :. Int) -> a
cumsum' arr f (sh :. outer) = Repa.sumAll $ sliceRange 0 outer $ Repa.slice arr (sh :. All)
{-# INLINE cumsum #-}
cumsum :: (FullShape sh ~ sh, Slice sh, Slice (SliceShape sh), Shape sh, Shape (SliceShape sh), Elt a, Num a) =>
Array (sh :. Int) a -> Array (sh :. Int) a
cumsum arr = Repa.force $ unsafeTraverse arr id $ cumsum' arr