这里有一个基本的monad问题,与Repa无关,再加上几个特定于Repa的问题。修复3'性能和正确使用'现在'
我正在使用Repa3库。我无法获得高效的并行代码。如果我让我的函数返回延迟数组,我得到的代码非常慢,可以扩展到8个内核。这个代码每GHC分析器需要超过20GB的内存,并且比基本的Haskell unboxed向量慢几个数量级。另外,如果我让所有函数都返回Unboxed清单数组(仍尝试在函数中使用融合,例如当我执行'map'时),我得到的代码更快(仍然比使用Haskell unboxed矢量),它根本不会扩展,事实上,随着更多内核的增加,它的速度会变慢。
基于Repa算法中的FFT示例代码,似乎正确的方法是始终返回清单数组。有没有我应该返回延迟数组的情况?
FFT代码还充分利用'now'功能。但是,当我尝试在我的代码中使用它时发生类型错误:
type Arr t r = Array t DIM1 r
data CycRingRepa m r = CRTBasis (Arr U r)
| PowBasis (Arr U r)
fromArray :: forall m r t. (BaseRing m r, Unbox r, Repr t r) => Arr t r -> CycRingRepa m r
fromArray =
let mval = reflectNum (Proxy::Proxy m)
in \x ->
let sh:.n = extent x
in assert (mval == 2*n) PowBasis $ now $ computeUnboxedP $ bitrev x
代码无需'now'即可编译好。与“现在”,我得到以下错误:
Couldn't match type
r' with
Array U (Z :. Int) r' `r' is a rigid type variable bound by the type signature for fromArray :: (BaseRing m r, Unbox r, Repr t r) => Arr t r -> CycRingRepa m r at C:\Users\crockeea\Documents\Code\LatticeLib\CycRingRepa.hs:50:1 Expected type: CycRingRepa m r Actual type: CycRingRepa m (Array U DIM1 r)
我不认为this是我的问题。如果有人能够解释Monad如何在“现在”工作,那将会很有帮助。据我最好的估计,monad似乎在创造一个'Arr U(Arr Ur)'。我期待着一个'Arr U r',它会匹配数据构造函数模式。发生了什么,我该如何解决这个问题?
类型签名是:
computeUnboxedP :: Fill r1 U sh e => Array r1 sh e -> Array U sh e
now :: (Shape sh, Repr r e, Monad m) => Array r sh e -> m (Array r sh e)
这将是有帮助的,当它是适合使用“现在”的一个更好的主意。我应该明确地调用computeUnboxedP(如在FFT示例代码中),还是应该使用更通用的computeP(因为unbox部分是由我的数据类型推断的)? 我应该在数据类型CycRingRepa中存储延迟或清单数组吗?最终我还想要这个代码与Haskell整数一起工作。这是否需要我编写使用U数组以外其他代码的新代码,或者我可以编写多形态代码来创建用于unbox类型的U数组以及用于整数/盒装类型的其他数组?
我意识到这里有很多问题,我很欣赏任何/所有的答案!