Следующий код выдает (ужасную) ошибку «вложенного параллелизма» с 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
только на quickCheck prop_fmap
, он успешно завершит 100 тестов. Итак, похоже, что-то происходит с тестовой структурой (вероятно, более общая проблема с последовательностью монад), которая отличается от QuickCheck
.
Любые идеи о том, почему я получаю эту ошибку и как ее избежать, продолжая выполнять параллельные вычисления?
test-framework
является многопоточным. Это определенно приводит к вложенному параллелизму. Спасибо, что напомнили мне об этом вопросе! - person crockeea   schedule 16.06.2016