I am trying this REPA library, and i want to process an image in both ways, parallel and sequentially.
I can read the image (with other library, DevIL) and process it with computeP (parallel). Here is the code (is from a example on the wiki of haskell).
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)
Now i want to do it sequentially changing "computeP" with "computeS". But, when i try to compile it, this error appears:
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)
As you can probably guess, i am new at functional programming. I dont know why this error is happening. Any help would be great.
Thanks in advance.
You are doing everything almost right. The error you are getting is due to the fact that
computePis monadic, whilecomputeSis not. If you compare their type signatures closely the difference that is biting you is theMonad mrestriction and return typem (Array r2 sh e)forcomputePvs(Array r2 sh e)forcomputeS. So long story short, just changeto:
The reason why parallel computation in Repa must be monadic has to do partially with lazyness, but mostly with Repa's inability to deal with nested parallelism. Sequential property of a
Monadsolves it for the most part:Using
donotation above (and the fact thatcomputePusesdeepSeqArrayunder the hood) makes surerotated1is evaluated before getting to second call tocomputeP. But sincecomputeSdoesn't use Repa's parallel scheduler it doesn't have that issue, thus doesn't need to use that property of aMonadand this code will work just fine: