gpt4 book ai didi

haskell - 使用 repa 时将 Identity monad 与 mmultP 一起使用有什么问题?

转载 作者:行者123 更新时间:2023-12-02 13:56:51 25 4
gpt4 key购买 nike

我不明白为什么这个程序使用 repa :

import Data.Array.Repa
import Data.Array.Repa.Algorithms.Matrix
import Data.Functor.Identity

go = runIdentity $ do
let mat = fromListUnboxed (ix2 2 2) [1..4]
let ins = fromListUnboxed (ix2 2 1) [1, 1]
mmultP mat ins

给我以下警告:

Data.Array.Repa: Performing nested parallel computation sequentially.
You've probably called the 'compute' or 'copy' function while another
instance was already running. This can happen if the second version
was suspended due to lazy evaluation. Use 'deepSeqArray' to ensure
that each array is fully evaluated before you 'compute' the next one.

我没有嵌套计算,我没有调用computecopy,并且我用来进行计算的所有内容都在同一个monad内。这与惰性评估有关吗?如果是这样,如何在使用 Identity monad 时进行并行计算(以保持整体计算的纯净)?

作为引用,将 runIdentity 替换为 runST 使其可以工作,尽管在任何一种情况下都根本没有使用特定 monad 的功能。

最佳答案

在computeP 和类似的并行操作中使用Monad 约束的原因是为了在需要时强制进行顺序计算。这在[Haskell 中的并行和并发编程]Monads 和computeP 小节中进行了描述。

就您而言,问题似乎是由 mmultP 的内部实现引起的:

mmultP  :: Monad m
=> Array U DIM2 Double
-> Array U DIM2 Double
-> m (Array U DIM2 Double)

mmultP arr brr
= [arr, brr] `deepSeqArrays`
do trr <- transpose2P brr
let (Z :. h1 :. _) = extent arr
let (Z :. _ :. w2) = extent brr
computeP
$ fromFunction (Z :. h1 :. w2)
$ \ix -> R.sumAllS
$ R.zipWith (*)
(unsafeSlice arr (Any :. (row ix) :. All))
(unsafeSlice trr (Any :. (col ix) :. All))

它首先调用 transpose2P,然后调用 computeP,并且 transpose2P 在内部调用 computeUnboxedP。如果您使用 Identity monad,则不会强制排序,因此这两个并行计算都可以并行运行,从而实现嵌套并行性。

如果您想保持纯粹,又不想使用 ST,则可以将 Identity 替换为 Eval ,这是 Identity 的严格版本:

import Control.Parallel.Strategies
...
go = runEval $ do ...

关于haskell - 使用 repa 时将 Identity monad 与 mmultP 一起使用有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37782489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com