许多并行应用程序的顺序转换在维修
在Repa中,我想要在我的数组的最内维上并行应用某个d
维线性变换,即在所有“列”向量上。
通常,这样的变换可以表示为矩阵M
,并且M*v
每个条目只是M
的适当行与v
的点积。 所以,我可以只使用traverse
与计算相应的点积的功能。 这花费d^2
工作。
但是,我的M
是特殊的:它承认线性工作顺序算法。 例如, M
可能是整个下三角形中1
s的下三角矩阵。 那么M*v
只是v
(即“扫描”)的部分和的向量。 这些总和可以以明显的方式顺序计算,但需要结果的(i-1)
st条目有效地计算第i
个条目。 (我有几个这样的M
,所有这些都可以按照线性顺序时间以某种方式计算)。
我没有看到任何明显的方式来使用traverse
(或任何其他的Repa函数)来利用M
的这个属性。 可以做到吗? 当存在如此快速的线性工作算法时,使用d^2
工作算法(即使具有丰富的并行性)将是相当浪费的。
(我看过一些旧的SO帖子(例如,在这里)提出了类似的问题,但没有什么与我的情况完全匹配。)
UPDATE
这里请求的是一些说明性代码,用于计算部分和的M
(如上所述)。 正如我所料,运行时(工作)在d
中超线性增长, d
是数组范围的第二个参数( ext
)。 这是由于mulM'
只指定如何计算输出的第i
个条目,而与所有其他条目无关。 即使在数组的总大小中有一个线性时间算法,我也不知道如何在Repa中表达它。
有趣的是,如果我从main
删除定义清单array'
的行,那么运行时只会在数组的总大小中线性缩放! 所以当数组“延迟”延迟时,融合/优化必须以某种方式提取线性工作算法,但没有任何明确的帮助。 这很神奇,但对我来说也不是很有用,因为实际上我需要在清单数组上调用mulM
。
{-# LANGUAGE TypeOperators, ScopedTypeVariables, FlexibleContexts #-}
module Main where
import Data.Array.Repa as R
-- multiplication by M across innermost dimension
mulM arr = traverse arr id mulM'
where mulM' _ idx@(i' :. i) =
sumAllS $ extract (Z:.0) (Z:.(i+1)) $ slice arr (i' :. All)
ext = Z :. (1000000::Int) :. (10::Int) -- super-linear runtime in 2nd arg
--ext = Z :. (10::Int) :. (1000000::Int) -- takes forever
array = fromFunction ext ((Z:.j:.i) -> j+i)
main :: IO ()
main = do
-- apply mulM to a manifest array
array' :: Array U DIM2 Int <- computeP $ array
ans :: Array U DIM2 Int <- computeP $ mulM array'
print "done"
链接地址: http://www.djcxy.com/p/59981.html
上一篇: many parallel applications of a sequential transform in repa