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が、役に立ちません。テストは独立しているため (ランダム性の順序付けは別として)、この例でネストされた並列処理がどのように可能であるかは明確ではありません。

興味深いことに、mainjust に変更するとquickCheck prop_fmap、100 回のテストが正常に完了します。そのため、テスト フレームワーク (おそらくモナド シーケンスのより一般的な問題) とは異なる何かが起こっているようですQuickCheck

このエラーが発生する理由と、並列計算を実行しながらエラーを回避する方法についてのアイデアはありますか?

注:Identityモナドの使用: ref1ref2

4

1 に答える 1

1

問題は、test-framework暗黙的にマルチスレッド化されていることです (たとえば、これを参照してください)。

私にとってうまくいく解決策はdefaultMainWithArgs、オプションで実行すること--threads=1です。

于 2016-06-16T12:16:50.693 に答える