修复中的嵌套并行
以下代码在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
。
上一篇: Nested Parallelism in Repa
下一篇: many parallel applications of a sequential transform in repa