REPA:computeS 和 computeP?
REPA: computeS and computeP?
我正在尝试这个 REPA 库,我想以两种方式处理图像,并行和顺序。
我可以读取图像(使用其他库,DevIL)并使用 computeP(并行)处理它。这是代码(来自 haskell 的 wiki 上的示例)。
import Foreign.Ptr
import System.Environment
import Data.Word
import Data.Array.Repa hiding ((++))
import Data.Array.Repa.IO.DevIL
import Data.Array.Repa.Repr.ForeignPtr
main :: IO ()
main = do
[f] <- getArgs
(RGB v) <- runIL $ readImage f
rotated <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
runIL $ writeImage ("flip-"++f) (RGB rotated)
rot180 :: (Source r e) => Array r DIM3 e -> Array D DIM3 e
rot180 g = backpermute e flop g
where
e@(Z :. x :. y :. _) = extent g
flop (Z :. i :. j :. k) =
(Z :. x - i - 1 :. y - j - 1 :. k)
现在我想依次将 "computeP" 更改为 "computeS"。
但是,当我尝试编译它时,出现了这个错误:
Couldn't match expected type ‘IO (Array F DIM3 Word8)’
with actual type ‘Array r20 DIM3 Word8’
In a stmt of a 'do' block:
rotated <- (computeS $ rot180 v) :: IO (Array F DIM3 Word8)
您可能猜到了,我是函数式编程的新手。我不知道为什么会发生此错误。任何帮助都会很棒。
提前致谢。
你做的几乎都是对的。您得到的错误是由于 computeP
是一元的,而 computeS
不是。如果你仔细比较它们的类型签名,你会发现的区别是 Monad m
限制和 return 类型 m (Array r2 sh e)
for computeP
vs (Array r2 sh e)
for computeS
.长话短说,只是改变
rotated <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
至:
let rotated = (computeS $ rot180 v) :: (Array F DIM3 Word8)
Repa 中的并行计算必须是 monadic 的原因部分与惰性有关,但主要是 Repa 无法处理嵌套并行性。 Monad
的顺序 属性 解决了大部分问题:
rotated1 <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
rotated2 <- (computeP $ rot180 rotated1) :: IO (Array F DIM3 Word8)
使用上面的 do
表示法(以及 computeP
在幕后使用 deepSeqArray
的事实)确保 rotated1
在第二次调用 computeP
。但是由于 computeS
不使用 Repa 的并行调度程序,所以它没有那个问题,因此不需要使用 Monad
的 属性 并且这段代码可以正常工作:
let rotated1 = computeS (rot180 v) :: Array F DIM3 Word8
rotated2 = computeS (rot180 rotated1) :: Array F DIM3 Word8
我正在尝试这个 REPA 库,我想以两种方式处理图像,并行和顺序。
我可以读取图像(使用其他库,DevIL)并使用 computeP(并行)处理它。这是代码(来自 haskell 的 wiki 上的示例)。
import Foreign.Ptr
import System.Environment
import Data.Word
import Data.Array.Repa hiding ((++))
import Data.Array.Repa.IO.DevIL
import Data.Array.Repa.Repr.ForeignPtr
main :: IO ()
main = do
[f] <- getArgs
(RGB v) <- runIL $ readImage f
rotated <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
runIL $ writeImage ("flip-"++f) (RGB rotated)
rot180 :: (Source r e) => Array r DIM3 e -> Array D DIM3 e
rot180 g = backpermute e flop g
where
e@(Z :. x :. y :. _) = extent g
flop (Z :. i :. j :. k) =
(Z :. x - i - 1 :. y - j - 1 :. k)
现在我想依次将 "computeP" 更改为 "computeS"。 但是,当我尝试编译它时,出现了这个错误:
Couldn't match expected type ‘IO (Array F DIM3 Word8)’
with actual type ‘Array r20 DIM3 Word8’
In a stmt of a 'do' block:
rotated <- (computeS $ rot180 v) :: IO (Array F DIM3 Word8)
您可能猜到了,我是函数式编程的新手。我不知道为什么会发生此错误。任何帮助都会很棒。
提前致谢。
你做的几乎都是对的。您得到的错误是由于 computeP
是一元的,而 computeS
不是。如果你仔细比较它们的类型签名,你会发现的区别是 Monad m
限制和 return 类型 m (Array r2 sh e)
for computeP
vs (Array r2 sh e)
for computeS
.长话短说,只是改变
rotated <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
至:
let rotated = (computeS $ rot180 v) :: (Array F DIM3 Word8)
Repa 中的并行计算必须是 monadic 的原因部分与惰性有关,但主要是 Repa 无法处理嵌套并行性。 Monad
的顺序 属性 解决了大部分问题:
rotated1 <- (computeP $ rot180 v) :: IO (Array F DIM3 Word8)
rotated2 <- (computeP $ rot180 rotated1) :: IO (Array F DIM3 Word8)
使用上面的 do
表示法(以及 computeP
在幕后使用 deepSeqArray
的事实)确保 rotated1
在第二次调用 computeP
。但是由于 computeS
不使用 Repa 的并行调度程序,所以它没有那个问题,因此不需要使用 Monad
的 属性 并且这段代码可以正常工作:
let rotated1 = computeS (rot180 v) :: Array F DIM3 Word8
rotated2 = computeS (rot180 rotated1) :: Array F DIM3 Word8