parallel matrix multiply (dph, par/pseq)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

parallel matrix multiply (dph, par/pseq)

Johannes Waldmann
Hello.

How can I multiply matrices (of Doubles)
with dph (-0.4.0)?  (ghc-6.12.1)  -  I was trying

type Vector = [:Double:]
type Matrix = [:Vector:]

times :: Matrix -> Matrix -> Matrix
times a b =
      mapP
      ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col  ) )
                      ( transposeP b )
      ) a

but there is no such thing as transposeP.

When I try any kind of index manipulations,
the compiler invariably tells me
that it does not want to build  [: :] - lists of indices
(e.g., there is no enumFromToP)
(I guess because I'm using Data.Array.Parallel.Prelude.Double)

Puzzled - J.W.


PS: what's the recommended way to multiply matrices
(better modelled as   Array (Int,Int) Double   or  [[Double]] ?)
with the  par/pseq  approach (if this is recommended at all)?

As I said earlier, I just want to have some nice and easy benchmarks
for demonstration in a lecture (to be run on 2, 4, or 8 cores).
Of course if they work, I'd use them in real life as well...




_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe

signature.asc (268 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: parallel matrix multiply (dph, par/pseq)

Rafael Gustavo da Cunha Pereira Pinto-2
I never used DPH, but for Matrices, I always tend to use Array (Int,Int) Double, as it accesses its elements in O(1). Arrays also can be unboxed (UArray), which are much faster, or monadic and mutable (MArray), which are more flexible.

I don't know if it is possible to use Arrays with DPH...




On Sun, Jan 17, 2010 at 21:35, Johannes Waldmann <[hidden email]> wrote:
Hello.

How can I multiply matrices (of Doubles)
with dph (-0.4.0)?  (ghc-6.12.1)  -  I was trying

type Vector = [:Double:]
type Matrix = [:Vector:]

times :: Matrix -> Matrix -> Matrix
times a b =
     mapP
     ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col  ) )
                     ( transposeP b )
     ) a

but there is no such thing as transposeP.

When I try any kind of index manipulations,
the compiler invariably tells me
that it does not want to build  [: :] - lists of indices
(e.g., there is no enumFromToP)
(I guess because I'm using Data.Array.Parallel.Prelude.Double)

Puzzled - J.W.


PS: what's the recommended way to multiply matrices
(better modelled as   Array (Int,Int) Double   or  [[Double]] ?)
with the  par/pseq  approach (if this is recommended at all)?

As I said earlier, I just want to have some nice and easy benchmarks
for demonstration in a lecture (to be run on 2, 4, or 8 cores).
Of course if they work, I'd use them in real life as well...




_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe




--
Rafael Gustavo da Cunha Pereira Pinto


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: parallel matrix multiply (dph, par/pseq)

Bertram Felgenhauer-2
In reply to this post by Johannes Waldmann
Johannes Waldmann wrote:

> Hello.
>
> How can I multiply matrices (of Doubles)
> with dph (-0.4.0)?  (ghc-6.12.1)  -  I was trying
>
> type Vector = [:Double:]
> type Matrix = [:Vector:]
>
> times :: Matrix -> Matrix -> Matrix
> times a b =
>       mapP
>       ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col  ) )
>                       ( transposeP b )
>       ) a
>
> but there is no such thing as transposeP.

It's possible to implement transposeP as follows,

    {-# LANGUAGE PArr #-}
    ...
    import qualified Data.Array.Parallel.Prelude.Int as I
   
    transposeP :: Matrix -> Matrix
    transposeP a = let
        h = lengthP a
        w = lengthP (a !: 0)
        rh = I.enumFromToP 0 (h I.- 1) -- or [: 0 .. h I.- 1 :]
        rw = I.enumFromToP 0 (w I.- 1) -- or [: 0 .. w I.- 1 :]
      in
        if h == 0 then [: :]
                  else mapP (\y -> mapP (\x -> a !: x !: y) rh) rw

Maybe there is a better way?

Bertram

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: parallel matrix multiply (dph, par/pseq)

Johannes Waldmann
In reply to this post by Rafael Gustavo da Cunha Pereira Pinto-2

> ... use Array (Int,Int) Double, as it accesses its elements in O(1).

thanks for the comments.

I don't need O(dim^0) element access -
I need O(dim^reasonable) addition and multiplication.

Modelling a matrix as [[Element]] should be nearly fine
(for sequential execution), I think these are quadratic/cubic:

a * b = zipWith (zipWith (+)) a b  
a * b = for a $ \ row ->
        for ( transpose b ) $ \ col ->
            sum $ zipWith (*) row col

The only problem with this code is that 'transpose b'
(assuming the compiler lifts it to outer scope)
allocates memory that later becomes garbage,
but not immediately, since it is needed several times.

( in the above, for = flip map  ,
which is missing from the standard libs?
by analogy to  forM = flip mapM )

Best regards, J.W.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe