Parallel compilation and execution?

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

Parallel compilation and execution?

michael rice-3
How do I compile and run this parallel program?

Michael

===========================

import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (seq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)

{-
nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)
-}


main = do putStrLn $ show $ nfib 39

===========================

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[michael@hostname ~]$ ./nfib +RTS -N3
nfib: the flag -N3 requires the program to be built with -threaded
nfib: 
nfib: Usage: <prog> <args> [+RTS <rtsopts> | -RTS <args>] ... --RTS <args>
nfib: 
nfib:    +RTS    Indicates run time system options follow
nfib:    -RTS    Indicates program arguments follow
nfib:   --RTS    Indicates that ALL subsequent arguments will be given to the
nfib:            program (including any of these RTS flags)
nfib: 
nfib: The following run time system options are available:
nfib: 
nfib:   -?       Prints this message and exits; the program is not executed
nfib:   --info   Print information about the RTS used by this program
nfib: 
nfib:   -K<size> Sets the maximum stack size (default 8M)  Egs: -K32k   -K512k
nfib:   -k<size> Sets the initial thread stack size (default 1k)  Egs: -k4k   -k2m
nfib: 
nfib:   -A<size> Sets the minimum allocation area size (default 512k) Egs: -A1m -A10k
nfib:   -M<size> Sets the maximum heap size (default unlimited)  Egs: -M256k -M1G
nfib:   -H<size> Sets the minimum heap size (default 0M)   Egs: -H24m  -H1G
nfib:   -m<n>    Minimum % of heap which must be available (default 3%)
nfib:   -G<n>    Number of generations (default: 2)
nfib:   -T<n>    Number of steps in younger generations (default: 2)
nfib:   -c<n>    Use in-place compaction instead of copying in the oldest generation
nfib:            when live data is at least <n>% of the maximum heap size set with
nfib:            -M (default: 30%)
nfib:   -c       Use in-place compaction for all oldest generation collections
nfib:            (the default is to use copying)
nfib:   -w       Use mark-region for the oldest generation (experimental)
nfib: 
nfib:   -t[<file>] One-line GC statistics (if <file> omitted, uses stderr)
nfib:   -s[<file>] Summary  GC statistics (if <file> omitted, uses stderr)
nfib:   -S[<file>] Detailed GC statistics (if <file> omitted, uses stderr)
nfib: 
nfib: 
nfib:   -Z       Don't squeeze out update frames on stack overflow
nfib:   -B       Sound the bell at the start of each garbage collection
nfib: 
nfib:   -hT      Heap residency profile (output file <program>.hp)
nfib:   -i<sec>  Time between heap samples (seconds, default: 0.1)
nfib: 
nfib:   -C<secs>  Context-switch interval in seconds.
nfib:             0 or no argument means switch as often as possible.
nfib:             Default: 0.02 sec; resolution is set by -V below.
nfib:   -V<secs>  Master tick interval in seconds (0 == disable timer).
nfib:             This sets the resolution for -C and the profile timer -i.
nfib:             Default: 0.02 sec.
nfib: 
nfib:   --install-signal-handlers=<yes|no>
nfib:             Install signal handlers (default: yes)
nfib: 
nfib: RTS options may also be specified using the GHCRTS environment variable.
nfib: 
nfib: Other RTS options may be available for programs compiled a different way.
nfib: The GHC User's Guide has full details.
nfib: 
[michael@hostname ~]$ 


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

Re: Parallel compilation and execution?

Daniel Fischer
On Thursday 26 May 2011 13:24:09, michael rice wrote:
> How do I compile and run this parallel program?
> Michael
> ===========================
> import Control.Parallel
> nfib :: Int -> Int
> nfib n | n <= 1 = 1      
>        | otherwise = par n1 (seq n2 (n1 + n2 + 1))

The 'seq' here should be a 'pseq' to ensure that n2 is (started to be)
calculated before (n1 + n2 +1) is evaluated (iirc, currently, both work
with ghc, but it's not guaranteed for seq).
 

>          where
>            n1 = nfib (n-1)              
>            n2 = nfib (n-2)
>  {-nfib :: Int -> Intnfib n | n <= 1 = 1
>           | otherwise = nfib (n-1) + nfib (n-2)-}
>
> main = do putStrLn $ show $ nfib 39
> ===========================
> [michael@hostname ~]$ ghc --make -threaded nfib.hs
> [michael@hostname ~]$ ./nfib +RTS -N3

In principle, that is the correct way to compile and run it (note that with
ghc-7, you don't need the --make).

> nfib: the flag -N3 requires the program to be built with
> -threaded

Have you previously compiled the programme without -threaded?
Unless you snipped the compilation messages, their absence strongly
indicates so.

If that is the case, you fell victim to ghc's recompilation-avoidance which
doesn't keep track of the flags a programme/module was compiled with, so it
saw that nothing [as far as it knows] changed, hence didn't recompile.

Then removing .o and .hi or passing -fforce-recomp will make it recompile
and link with the threaded runtime.

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

Re: Parallel compilation and execution?

michael rice-3
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 


--- On Thu, 5/26/11, Daniel Fischer <[hidden email]> wrote:

From: Daniel Fischer <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: [hidden email]
Cc: "michael rice" <[hidden email]>
Date: Thursday, May 26, 2011, 8:16 AM

On Thursday 26 May 2011 13:24:09, michael rice wrote:
> How do I compile and run this parallel program?
> Michael
> ===========================
> import Control.Parallel
> nfib :: Int -> Int
> nfib n | n <= 1 = 1       
>        | otherwise = par n1 (seq n2 (n1 + n2 + 1))

The 'seq' here should be a 'pseq' to ensure that n2 is (started to be)
calculated before (n1 + n2 +1) is evaluated (iirc, currently, both work
with ghc, but it's not guaranteed for seq).

>          where
>            n1 = nfib (n-1)               
>            n2 = nfib (n-2)
>  {-nfib :: Int -> Intnfib n | n <= 1 = 1
>           | otherwise = nfib (n-1) + nfib (n-2)-}
>
> main = do putStrLn $ show $ nfib 39
> ===========================
> [michael@hostname ~]$ ghc --make -threaded nfib.hs
> [michael@hostname ~]$ ./nfib +RTS -N3

In principle, that is the correct way to compile and run it (note that with
ghc-7, you don't need the --make).

> nfib: the flag -N3 requires the program to be built with
> -threaded

Have you previously compiled the programme without -threaded?
Unless you snipped the compilation messages, their absence strongly
indicates so.

If that is the case, you fell victim to ghc's recompilation-avoidance which
doesn't keep track of the flags a programme/module was compiled with, so it
saw that nothing [as far as it knows] changed, hence didn't recompile.

Then removing .o and .hi or passing -fforce-recomp will make it recompile
and link with the threaded runtime.

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

Re: Parallel compilation and execution?

David Virebayre


2011/5/26 michael rice <[hidden email]>
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Why do you add n1+n2+1 in the parallel program, but only n1+n2 in the non-parallel one ?
 

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 



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

Re: Parallel compilation and execution?

Brandon Moore-2
In reply to this post by michael rice-3
>From: michael rice, Thursday, May 26, 2011
>Subject: Re: [Haskell-cafe] Parallel compilation and execution?
>
>Thank, Daniel
>
>Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.


Not exactly twice - (2n-1). What you get from counting all nodes in a binary tree (of function calls),
compared to counting just the leaves.

A program using only pure code, par, and pseq should be deterministic, so if it gets different
value by building with and without threaded, changing the number of threads, or just running
again, that's a bug in GHC (If it runs out of memory sometimes and not other times, that's
not technically a bug, but still interesting).


Replacing par with the second argument should also give an equivalent program. pseq isn't
really parallel at all, but if you'd like to remove it, then replacing it with seq or just the second
argument might change strictness and evaluation order, but shouldn't change the result.
Brandon.


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

Re: Parallel compilation and execution?

michael rice-3
In reply to this post by David Virebayre
Fair question. I copied the parallel version from:

http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

but pulled the non-parallel version from a text.

Michael


--- On Thu, 5/26/11, David Virebayre <[hidden email]> wrote:

From: David Virebayre <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "michael rice" <[hidden email]>
Cc: [hidden email], "Daniel Fischer" <[hidden email]>
Date: Thursday, May 26, 2011, 8:56 AM



2011/5/26 michael rice <nowgate@...>
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Why do you add n1+n2+1 in the parallel program, but only n1+n2 in the non-parallel one ?
 

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 



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

Re: Parallel compilation and execution?

michael rice-3
Are the tools of Control.Parallel comparable to OpenMP?

Michael

--- On Thu, 5/26/11, michael rice <[hidden email]> wrote:

From: michael rice <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "David Virebayre" <[hidden email]>
Cc: "Daniel Fischer" <[hidden email]>, [hidden email]
Date: Thursday, May 26, 2011, 9:32 AM

Fair question. I copied the parallel version from:

http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

but pulled the non-parallel version from a text.

Michael


--- On Thu, 5/26/11, David Virebayre <[hidden email]> wrote:

From: David Virebayre <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "michael rice" <[hidden email]>
Cc: [hidden email], "Daniel Fischer" <[hidden email]>
Date: Thursday, May 26, 2011, 8:56 AM



2011/5/26 michael rice <[hidden email]>
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Why do you add n1+n2+1 in the parallel program, but only n1+n2 in the non-parallel one ?
 

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 



-----Inline Attachment Follows-----

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

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

Re: Parallel compilation and execution?

Axman
Hi Michael,

OpenMP is a very different beast, and was developed to help get over the shortcomings that languages like C and FORTRAN have with respect to parallel and concurrent programming (pthreads were about all there was before OpenMP). OpenMP lets you specify regions of code that should be run in multiple threads at once, each with a unique ID.  Here is an example of (part of) a parallel merge sort I've been working on

static void
pmergesort(long int * in, long int * tmp, long int n, int nthread)
{
    long int nhalf = n/2;

    if(n <= N_small)
    {
        insertsort1(in, n);
        return;
    }

    if(nthread > 1)
    {
        #pragma omp parallel num_threads(2)
        {
            if(omp_get_thread_num() == 0)
                 pmergesort(tmp,       in,         nhalf, nthread>>1);
            else pmergesort(tmp+nhalf, in+nhalf, n-nhalf, nthread>>1);
        }
    } else {
        mergesort3(tmp,       in,         nhalf);
        mergesort3(tmp+nhalf, in+nhalf, n-nhalf);
    }

    merge( tmp, in, nhalf, n);
}

The approach that Control.Concurrent takes is very different, preferring a style where the programmer says what things might be advantageous to run in parallel, but the runtime makes no guarantees that they will be, allowing the programmer to break work down into smaller chunks, and letting the runtime sort out which parts should be run concurrently. This allows for a much easier style of parallel programming, but is only really possible in a pure language like Haskell. 

On a side note, the Cilk language, which adds a small number of keywords like fork and sync to the C language takes an approach closer to what Control.Parallel does, but it's not a graceful, and IMO not as easy to use.

Hope that helps. I've been having a lot of fun over the last few weeks playing with OpenMP for a university assignment, and I've got to say I greatly prefer the haskell way of doing things.

Cheers,
Alex Mason

On 27/05/2011, at 10:23, michael rice wrote:

Are the tools of Control.Parallel comparable to OpenMP?

Michael

--- On Thu, 5/26/11, michael rice <[hidden email]> wrote:

From: michael rice <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "David Virebayre" <[hidden email]>
Cc: "Daniel Fischer" <[hidden email]>, [hidden email]
Date: Thursday, May 26, 2011, 9:32 AM

Fair question. I copied the parallel version from:

http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

but pulled the non-parallel version from a text.

Michael


--- On Thu, 5/26/11, David Virebayre <[hidden email]> wrote:

From: David Virebayre <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "michael rice" <[hidden email]>
Cc: [hidden email], "Daniel Fischer" <[hidden email]>
Date: Thursday, May 26, 2011, 8:56 AM



2011/5/26 michael rice <[hidden email]>
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Why do you add n1+n2+1 in the parallel program, but only n1+n2 in the non-parallel one ?
 

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 



-----Inline Attachment Follows-----

_______________________________________________
Haskell-Cafe mailing list
<a ymailto="mailto:Haskell-Cafe@haskell.org" href="x-msg://158/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

Re: Parallel compilation and execution?

Simon Marlow-7
In reply to this post by michael rice-3
On 26/05/2011 14:32, michael rice wrote:
> Fair question. I copied the parallel version from:
>
> <http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html>
> http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

That is the User Guide for GHC 6.6, incidentally.  If you're using a
later version of GHC (highly recommended especially for parallel stuff),
then you should look at the docs for your version.

Cheers,
        Simon




>
> <http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html>but
> pulled the non-parallel version from a text.
>
> Michael
>
>
> --- On *Thu, 5/26/11, David Virebayre /<[hidden email]>/* wrote:
>
>
>     From: David Virebayre <[hidden email]>
>     Subject: Re: [Haskell-cafe] Parallel compilation and execution?
>     To: "michael rice" <[hidden email]>
>     Cc: [hidden email], "Daniel Fischer"
>     <[hidden email]>
>     Date: Thursday, May 26, 2011, 8:56 AM
>
>
>
>     2011/5/26 michael rice <[hidden email]
>     </mc/compose?to=[hidden email]>>
>
>         Thank, Daniel
>
>         Multiple threads are in evidence in my system monitor, but I
>         wonder why I'm getting two different answers, one twice the
>         other. The first is the parallel solution and the second is the non.
>
>
>     Why do you add n1+n2+1 in the parallel program, but only n1+n2 in
>     the non-parallel one ?
>
>
>         Michael
>
>         ===========
>
>         {-
>         import Control.Parallel
>
>         nfib :: Int -> Int
>         nfib n | n <= 1 = 1
>         | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
>         where n1 = nfib (n-1)
>         n2 = nfib (n-2)
>         -}
>
>         nfib :: Int -> Int
>         nfib n | n <= 1 = 1
>         | otherwise = nfib (n-1) + nfib (n-2)
>
>         main = do putStrLn $ show $ nfib 39
>
>         =============
>
>         [michael@hostname ~]$ ghc --make -threaded nfib.hs
>         [1 of 1] Compiling Main ( nfib.hs, nfib.o )
>         Linking nfib ...
>         [michael@hostname ~]$ ./nfib +RTS -N3
>         204668309
>         [michael@hostname ~]$ ghc --make nfib.hs
>         [1 of 1] Compiling Main ( nfib.hs, nfib.o )
>         Linking nfib ...
>         [michael@hostname ~]$ ./nfib
>         102334155
>         [michael@hostname ~]$
>
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe


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

Re: Parallel compilation and execution?

michael rice-3
In reply to this post by Axman
Hi Alex,

I had previously looked at OpenMP (Fortran) and when I saw par and seq in Control.Parallel I got a sense of common terminology, sections of code that can be executed in parallel and sections of code that must be executed sequentially. I haven't looked at Control.Concurrent yet.

The original reason I took a look at Haskell (and Erlang) was multi-core CPUs were becoming common and I wanted to learn to take advantage of them, but Haskell's learning curve has been so steep I've been occupied with learning other aspects of the language and only now have turned again to try my hand at its parallelizing features.

Thanks,

Michael 

--- On Fri, 5/27/11, Alex Mason <[hidden email]> wrote:

From: Alex Mason <[hidden email]>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "michael rice" <[hidden email]>
Cc: "David Virebayre" <[hidden email]>, [hidden email], "Daniel Fischer" <[hidden email]>
Date: Friday, May 27, 2011, 6:05 AM

Hi Michael,

OpenMP is a very different beast, and was developed to help get over the shortcomings that languages like C and FORTRAN have with respect to parallel and concurrent programming (pthreads were about all there was before OpenMP). OpenMP lets you specify regions of code that should be run in multiple threads at once, each with a unique ID.  Here is an example of (part of) a parallel merge sort I've been working on

static void
pmergesort(long int * in, long int * tmp, long int n, int nthread)
{
    long int nhalf = n/2;

    if(n <= N_small)
    {
        insertsort1(in, n);
        return;
    }

    if(nthread > 1)
    {
        #pragma omp parallel num_threads(2)
        {
            if(omp_get_thread_num() == 0)
                 pmergesort(tmp,       in,         nhalf, nthread>>1);
            else pmergesort(tmp+nhalf, in+nhalf, n-nhalf, nthread>>1);
        }
    } else {
        mergesort3(tmp,       in,         nhalf);
        mergesort3(tmp+nhalf, in+nhalf, n-nhalf);
    }

    merge( tmp, in, nhalf, n);
}

The approach that Control.Concurrent takes is very different, preferring a style where the programmer says what things might be advantageous to run in parallel, but the runtime makes no guarantees that they will be, allowing the programmer to break work down into smaller chunks, and letting the runtime sort out which parts should be run concurrently. This allows for a much easier style of parallel programming, but is only really possible in a pure language like Haskell. 

On a side note, the Cilk language, which adds a small number of keywords like fork and sync to the C language takes an approach closer to what Control.Parallel does, but it's not a graceful, and IMO not as easy to use.

Hope that helps. I've been having a lot of fun over the last few weeks playing with OpenMP for a university assignment, and I've got to say I greatly prefer the haskell way of doing things.

Cheers,
Alex Mason

On 27/05/2011, at 10:23, michael rice wrote:

Are the tools of Control.Parallel comparable to OpenMP?

Michael

--- On Thu, 5/26/11, michael rice <nowgate@...> wrote:

From: michael rice <nowgate@...>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "David Virebayre" <dav.vire+haskell@...>
Cc: "Daniel Fischer" <daniel.is.fischer@...>, haskell-cafe@...
Date: Thursday, May 26, 2011, 9:32 AM

Fair question. I copied the parallel version from:

http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

but pulled the non-parallel version from a text.

Michael


--- On Thu, 5/26/11, David Virebayre <dav.vire+haskell@...> wrote:

From: David Virebayre <dav.vire+haskell@...>
Subject: Re: [Haskell-cafe] Parallel compilation and execution?
To: "michael rice" <nowgate@...>
Cc: haskell-cafe@..., "Daniel Fischer" <daniel.is.fischer@...>
Date: Thursday, May 26, 2011, 8:56 AM



2011/5/26 michael rice <[hidden email]>
Thank, Daniel

Multiple threads are in evidence in my system monitor, but I wonder why I'm getting two different answers, one twice the other. The first is the parallel solution and the second is the non.

Why do you add n1+n2+1 in the parallel program, but only n1+n2 in the non-parallel one ?
 

Michael

===========

{-
import Control.Parallel

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)
-}

nfib :: Int -> Int
nfib n | n <= 1 = 1
       | otherwise = nfib (n-1) + nfib (n-2)

main = do putStrLn $ show $ nfib 39

=============

[michael@hostname ~]$ ghc --make -threaded nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib +RTS -N3
204668309
[michael@hostname ~]$ ghc --make nfib.hs
[1 of 1] Compiling Main             ( nfib.hs, nfib.o )
Linking nfib ...
[michael@hostname ~]$ ./nfib
102334155
[michael@hostname ~]$ 



-----Inline Attachment Follows-----

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


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

Re: Parallel compilation and execution?

michael rice-3
In reply to this post by Simon Marlow-7
Oops! Guess I'm going to have to refine my searching techniques. Thanks, Simon.

Michael

--- On Fri, 5/27/11, Simon Marlow <[hidden email]> wrote:

From: Simon Marlow <[hidden email]>
Subject: Re: Parallel compilation and execution?
To: "michael rice" <[hidden email]>
Cc: "David Virebayre" <[hidden email]>, "Daniel Fischer" <[hidden email]>, [hidden email]
Date: Friday, May 27, 2011, 7:08 AM

On 26/05/2011 14:32, michael rice wrote:
> Fair question. I copied the parallel version from:
>
> <http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html>
> http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html

That is the User Guide for GHC 6.6, incidentally.  If you're using a
later version of GHC (highly recommended especially for parallel stuff),
then you should look at the docs for your version.

Cheers,
    Simon




>
> <http://www.haskell.org/ghc/docs/6.6/html/users_guide/lang-parallel.html>but
> pulled the non-parallel version from a text.
>
> Michael
>
>
> --- On *Thu, 5/26/11, David Virebayre /<dav.vire+haskell@...>/* wrote:
>
>
>     From: David Virebayre <dav.vire+haskell@...>
>     Subject: Re: [Haskell-cafe] Parallel compilation and execution?
>     To: "michael rice" <nowgate@...>
>     Cc: haskell-cafe@..., "Daniel Fischer"
>     <daniel.is.fischer@...>
>     Date: Thursday, May 26, 2011, 8:56 AM
>
>
>
>     2011/5/26 michael rice <nowgate@...
>     </mc/compose?to=nowgate@...>>
>
>         Thank, Daniel
>
>         Multiple threads are in evidence in my system monitor, but I
>         wonder why I'm getting two different answers, one twice the
>         other. The first is the parallel solution and the second is the non.
>
>
>     Why do you add n1+n2+1 in the parallel program, but only n1+n2 in
>     the non-parallel one ?
>
>
>         Michael
>
>         ===========
>
>         {-
>         import Control.Parallel
>
>         nfib :: Int -> Int
>         nfib n | n <= 1 = 1
>         | otherwise = par n1 (pseq n2 (n1 + n2 + 1))
>         where n1 = nfib (n-1)
>         n2 = nfib (n-2)
>         -}
>
>         nfib :: Int -> Int
>         nfib n | n <= 1 = 1
>         | otherwise = nfib (n-1) + nfib (n-2)
>
>         main = do putStrLn $ show $ nfib 39
>
>         =============
>
>         [michael@hostname ~]$ ghc --make -threaded nfib.hs
>         [1 of 1] Compiling Main ( nfib.hs, nfib.o )
>         Linking nfib ...
>         [michael@hostname ~]$ ./nfib +RTS -N3
>         204668309
>         [michael@hostname ~]$ ghc --make nfib.hs
>         [1 of 1] Compiling Main ( nfib.hs, nfib.o )
>         Linking nfib ...
>         [michael@hostname ~]$ ./nfib
>         102334155
>         [michael@hostname ~]$
>
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@...
> http://www.haskell.org/mailman/listinfo/haskell-cafe


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