修复中的嵌套并行

以下代码在repa-3.4.0.1中产生(可怕的)“嵌套并行性”错误:

import Control.Monad.Identity (runIdentity, liftM)
import Data.Array.Repa              as R
import Data.Array.Repa.Repr.Unboxed
import Data.Vector.Unboxed
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import Test.QuickCheck hiding (generate,output)

main :: IO ()
main = defaultMainWithArgs [prop,prop] ["--maximum-generated-tests=1"]

prop = testProperty "Test" $ property prop_fmap

prop_fmap :: Arr Int -> Bool
prop_fmap x = fmapT id x == x




newtype Arr r = Arr (Array U DIM1 r) deriving (Eq, Show)

instance (Arbitrary r, Unbox r) => Arbitrary (Arr r) where
    arbitrary = replM arbitrary
    shrink = shrinkNothing

replM :: (Unbox r, Monad mon) => mon r -> mon (Arr r)
replM = let n = 6
        in liftM (Arr . fromUnboxed (Z:.n)) . replicateM n

fmapT :: (Unbox a, Unbox b) => (a -> b) -> Arr a -> Arr b
fmapT f (Arr v) = Arr $ force' $ R.map f $ v

force' :: (Shape sh, Unbox r) => Array D sh r -> Array U sh r
force' = runIdentity . computeP

确切的错误是:

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. 

我正在用ghc Main -threaded Main +RTS -N2编译,并使用Main +RTS -N2运行。 我已经尝试在deepSeqArray的定义中使用fmapT ,但它没有帮助。 由于测试是独立的(除了对随机性进行排序),所以在这个例子中,如何嵌套并行是不可能的。

有趣的是,如果我将main更改为quickCheck prop_fmap ,它会成功完成100次测试。 因此,似乎有一些与QuickCheck不同的QuickCheck框架(可能是monad测序的一个更常见的问题)正在发生。

任何想法,为什么我得到这个错误,以及如何我可以避免它,而仍然在做一个并行计算?

注意:使用Identity monad:ref1,ref2


问题在于test-framework隐式地是多线程的(参见例如)。

适用于我的解决方案是使用--threads=1选项运行defaultMainWithArgs

链接地址: http://www.djcxy.com/p/59983.html

上一篇: Nested Parallelism in Repa

下一篇: many parallel applications of a sequential transform in repa