3

以下代码使用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. 我试过deepSeqArray在定义中使用fmapT,但没有帮助。由于测试是独立的(除了对随机性进行排序),因此在此示例中甚至不清楚嵌套并行性是如何实现的。

有趣的是,如果我更改main为 just quickCheck prop_fmap,它会成功完成 100 次测试。因此,测试框架(可能是 monad 排序的更普遍问题)似乎与QuickCheck.

关于我为什么会收到此错误以及如何在仍然进行并行计算的同时避免它的任何想法?

注意:使用Identity单子:ref1ref2

4

1 回答 1

1

问题是test-framework隐式多线程(例如,请参见this。)

对我有用的解决方案是defaultMainWithArgs使用 option运行--threads=1

于 2016-06-16T12:16:50.693 回答