Actor question

classic Classic list List threaded Threaded
7 messages Options
tog
Reply | Threaded
Open this post in threaded view
|

Actor question

tog
Hi

I would like to use Actors to distribute the work to be done on the elements of a collection.

My code starts  like this ...

def observer
observer = actor {
    collection.each {item -> actor { observer << doWork(item) } }

...
}

Then I have some processing to be done on the result of doWork.

    def result

    def resNum = 0
    loop {
        resNum += 1
        if (resNum <= collection.size()) {
            react { tmp ->
                if (someCondition(tmp, result)) result = tmp
            }
        } else {
            println "Result is ${result}"
            stop()
        }
    }

I found this construct non intuitive and wonder if there exist some alternatives
Can we do something like:
def result
loop(collection.size()) {
    react { tmp ->
            if (someCondition(tmp, result)) result = tmp
    }
}
println "Result is ${result}"

Guillaume


   

Reply | Threaded
Open this post in threaded view
|

Re: Actor question

Dierk König
Hi Tog,

cool to see you here ;-)

> Can we do something like:
> def result
> loop(collection.size()) {
>     react { tmp ->
>             if (someCondition(tmp, result)) result = tmp
>     }
> }
> println "Result is ${result}"


Even though one could write an actor that
works like above, I wouldn't do so since
the use of "result" is not safe here.

Without knowing more about what problem you are
solving, I would investigate whether fork/join could
offer a solution.

cheers
Dierk



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Actor question

Russel Winder
In reply to this post by tog
On Sun, 2010-04-25 at 21:26 +0530, tog wrote:
> Hi
>
> I would like to use Actors to distribute the work to be done on the
> elements of a collection.

I am not convinced actors are what you want to use here.  The issue is
the control over the communications channels.  I would suggest that CSP
would make things easier.

>
> My code starts  like this ...
>
> def observer
> observer = actor {
>     collection.each {item -> actor { observer << doWork(item) } }
>
> ...
> }
>
No problem with the doWork functions sending messages, the problem is
that an actor is probably not the right tool as a receiver.

> Then I have some processing to be done on the result of doWork.
>
>     def result
>
>     def resNum = 0
>     loop {
>         resNum += 1
>         if (resNum <= collection.size()) {
>             react { tmp ->
>                 if (someCondition(tmp, result)) result = tmp
>             }
>         } else {
>             println "Result is ${result}"
>             stop()
>         }
>     }
>
> I found this construct non intuitive and wonder if there exist some
> alternatives
> Can we do something like:
> def result
> loop(collection.size()) {
>     react { tmp ->
>             if (someCondition(tmp, result)) result = tmp
>     }
> }
> println "Result is ${result}"
>
> Guillaume
Classic CSP would use:

        def result
        for ( i in 0 ..< collection.size ( ) ) {
                def nextValue = channel.in ( ).read ( )
                . . .
        }

I think the actor message passing processing is getting in the way of
your algorithm where CSP is more likely to fit what you want to do.

Unless of course I have missed something, which is entirely possible.
>

--
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:[hidden email]
41 Buckmaster Road    m: +44 7770 465 077   xmpp: [hidden email]
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

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

Re: Actor question

Vaclav
Administrator
In reply to this post by tog
Hi tog,

you've brought up an interesting idea of a counting "loop". It seems this pattern is somewhat recurring when people use actors and we might consider supporting it.

To your problem, seeing a collection that needs to be processed in parallel always makes me think about using "parallel collections". Have you considered using something like this (using the 0.10 beta-1 syntax here):

GParsPool.withPool {
    println 'Result it ' + collection.collectParallel{doWork it}.foldParallel{a, b -> someCondition(a, b) ? a : b}
}

or a bit more performant

GParsPool.withPool {
    println 'Result it ' + collection.parallel.map{doWork it}.reduce{a, b -> someCondition(a, b) ? a : b}
}

Regards,

Vaclav


On Sun, Apr 25, 2010 at 5:56 PM, tog <[hidden email]> wrote:
Hi

I would like to use Actors to distribute the work to be done on the elements of a collection.

My code starts  like this ...

def observer
observer = actor {
    collection.each {item -> actor { observer << doWork(item) } }

...
}

Then I have some processing to be done on the result of doWork.

    def result

    def resNum = 0
    loop {
        resNum += 1
        if (resNum <= collection.size()) {
            react { tmp ->
                if (someCondition(tmp, result)) result = tmp
            }
        } else {
            println "Result is ${result}"
            stop()
        }
    }

I found this construct non intuitive and wonder if there exist some alternatives
Can we do something like:
def result
loop(collection.size()) {
    react { tmp ->
            if (someCondition(tmp, result)) result = tmp
    }
}
println "Result is ${result}"

Guillaume


   




--
E-mail: [hidden email]
Blog: http://www.jroller.com/vaclav
Linkedin page: http://www.linkedin.com/in/vaclavpech
tog
Reply | Threaded
Open this post in threaded view
|

Re: Actor question

tog
In reply to this post by Dierk König
Hi Dierk & all

On Sun, Apr 25, 2010 at 9:55 PM, Dierk König <[hidden email]> wrote:
Hi Tog,

cool to see you here ;-)
Hehe actually I have been doing HPC & distributed computing for years, it's time to experiment it with Groovy & GPars :)
 

Without knowing more about what problem you are
solving, I would investigate whether fork/join could
offer a solution.

Actually I am playing around with GPars and I started with this example ...
     http://groovyconsole.appspot.com/view.groovy?id=12006
but I don't feel the construct very Groovy (I don't like the fact to have to count the number of elements in the collection)... and as you suggest it might not be very safe ;)

We should have a way to make this more concise and safe  ...

I am keen to use other models (fork and joins, CSP ...) but Actors should fit nicely in the picture as well.

Cheers
Guillaume

 
cheers
Dierk



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email





--
PGP KeyID: 1024D/69B00854  subkeys.pgp.net

http://cheztog.blogspot.com
tog
Reply | Threaded
Open this post in threaded view
|

Re: Actor question

tog
In reply to this post by Russel Winder
Hmmm looks pretty much like message passing I have been doing for many years using P4, PVM, MPI, ...
Can I mix both models: Actors & CSP ?
Does that support collective ops (reduce, ...) ?

Guillaume

On Sun, Apr 25, 2010 at 11:22 PM, Russel Winder <[hidden email]> wrote:
On Sun, 2010-04-25 at 21:26 +0530, tog wrote:
> Hi
>
> I would like to use Actors to distribute the work to be done on the
> elements of a collection.

I am not convinced actors are what you want to use here.  The issue is
the control over the communications channels.  I would suggest that CSP
would make things easier.
>
> My code starts  like this ...
>
> def observer
> observer = actor {
>     collection.each {item -> actor { observer << doWork(item) } }
>
> ...
> }
>
No problem with the doWork functions sending messages, the problem is
that an actor is probably not the right tool as a receiver.

> Then I have some processing to be done on the result of doWork.
>
>     def result
>
>     def resNum = 0
>     loop {
>         resNum += 1
>         if (resNum <= collection.size()) {
>             react { tmp ->
>                 if (someCondition(tmp, result)) result = tmp
>             }
>         } else {
>             println "Result is ${result}"
>             stop()
>         }
>     }
>
> I found this construct non intuitive and wonder if there exist some
> alternatives
> Can we do something like:
> def result
> loop(collection.size()) {
>     react { tmp ->
>             if (someCondition(tmp, result)) result = tmp
>     }
> }
> println "Result is ${result}"
>
> Guillaume

Classic CSP would use:

       def result
       for ( i in 0 ..< collection.size ( ) ) {
               def nextValue = channel.in ( ).read ( )
               . . .
       }

I think the actor message passing processing is getting in the way of
your algorithm where CSP is more likely to fit what you want to do.

Unless of course I have missed something, which is entirely possible.
>

--
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: [hidden email]
41 Buckmaster Road    m: +44 7770 465 077   xmpp: [hidden email]
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



--
PGP KeyID: 1024D/69B00854  subkeys.pgp.net

http://cheztog.blogspot.com
Reply | Threaded
Open this post in threaded view
|

Re: Actor question

Russel Winder
On Mon, 2010-04-26 at 07:41 +0530, tog wrote:
> Hmmm looks pretty much like message passing I have been doing for many
> years using P4, PVM, MPI, ...
> Can I mix both models: Actors & CSP ?
> Does that support collective ops (reduce, ...) ?
>
Crickey I haven't heard anyone mention PVM (as in Parallel Virtual
Machine nor Python Virtual Machine) in years, I thought MPI had swept it
from any use at all.

MPI is the de facto standard for SPMD cluster-style systems.  OpenMP is
making in roads as a thread handling system for per-node parallelism.
In the C++ world TBB is really, very, very good.  MPI can be used per
node as well.  Of course MPI and OpenMP are driven by the needs of
Fortran, with C and C++ using whatever they can.

There have been attempts to use MPI in Java but I think they have all
failed.  Two obvious reasons:

1.  The Java world is obsessed with threads.
2.  The MPI message passing model is Fortran-based.

OpenMP failed in the Java world as well, at least on its first pass.
Now with annotations I know of at least one group trying to rework
OpenMP for Java and they are having a far more successful go of it.
However it is still bringing a Fortran technology into Java, so there
are huge barriers to entry.

Go brings CSP inspired channels to the C-like world, so it is clear
which way Google think the world is going.

We mustn't forget the drive towards PGAS going on in some of the
Fortran/C/C++ world (by Chapel and Fortress) and the JVM world (X10 and
Fortress).  This is basically an attempt to bring shared memory
programming into the NUMA world of multicore clusters.  They are forging
ahead, but I suspect their real impact will be to force Fortran, C and C
++ to evolve, though given that these languages evolve only on a 10 year
standards committee based cycle it is hard to see them really staying
the course.

Erlang opted for actor-like/CSP-like processes and is very successful.
Scala opted for actors, but the current implementation reputedly has
problems which is why there are alternate implementations being built.

Of course we mustn't forget data parallelism -- which is why extras166y
must be taken into the Java 7 standard or Java will loose out.

So your question is actually very deep since you mention data parallel
operations and actors and CSP in the same sentence.  I would say that
GPars has

1. Actors
2. CSP
3. Dataflow
4. Data Parallelism

and that we should avoid inappropriate use of techniques from one on
another.  We need to promote idioms of use.  People need to map the
solution to their problem to the correct model and then use appropriate
idioms.

Where possible data parallelism is the easiest to work with in a
functional programming style -- which is why Haskell has such great
emphasis on it.  In the Scala world, Scalaz has some great tools.  As
indeed does Fortran, cf. co-arrays.

I guess what I am saying is that Actors, CSP and Dataflow introduce a
data structure in and of themselves and that trying to use them to work
another data structure is probably a bad idea.

--
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:[hidden email]
41 Buckmaster Road    m: +44 7770 465 077   xmpp: [hidden email]
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc (205 bytes) Download Attachment