Parallelism Map and Reduce
Ali Çehreli
acehreli at yahoo.com
Tue Dec 11 07:22:49 PST 2012
On 12/11/2012 02:53 AM, Zardoz wrote:
> auto acelByObjs = map!( (Entity o) {
> Vector3 r = o.pos[0] - pos[0];
> return r * (o.mass / pow((r.sq_length + epsilon2), 1.5));
> } )(objects);
> newAcel = reduce!("a + b")(acelByObjs);
>
> It works very well with the std.algorithm Map and Reduce but when I try
> to use std.parallelism versions of it, parallel Map give me this
> compilataion errors :
>
> entity.d(63): Error: template instance map!(delegate @system
> Vector3(Entity o)
> {
> Vector3 r = o.pos[0LU].opBinary(this.pos[0LU]);
> return r.opBinary(o.mass / pow(r.sq_length() + epsilon2,1.5));
> }
> ) cannot use local '__lambda3' as parameter to non-global template
> map(functions...)
That used to work a couple of dmd versions ago. I think it was a bug
that it worked, so it stopped working after bug fixes.
If I'm not mistaken this is actually related to a compiler
implementation issue: Lambda's have a single pointer to store the
context that they have been started in.
When a lambda is a free-standing function (aka "module function" or
"global function") then there is only the context to deal with. When the
template is a member function (taskPool.map is) then there is also the
object that the function is started on.
The single pointer of the lambda is not sufficient to store both without
big changes in the compiler.
(I may be off with that description above. e.g. there may be two
pointers when three are actually needed, etc.)
I had to change following chapter after dmd's behavior had changed:
http://ddili.org/ders/d.en/parallelism.html
--- Quoting ---
import std.parallelism;
// ...
double averageGrade(Student student)
{
return student.averageGrade;
}
// ...
auto results = taskPool.map!averageGrade(students, 3);
Note: The free-standing averageGrade() function above is needed due to a
limitation that involves using local delegates with member function
templates like TaskPool.map:
auto results = taskPool.map!(a => a.averageGrade)(students, 3);
// ← compilation ERROR
----------
As you see above, the solution is to use a function with taskPool.map,
not a lambda.
Ali
More information about the Digitalmars-d-learn
mailing list