www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Troubles with taskPool.amap, lambdas and more

reply "bearophile" <bearophileHUGS lycos.com> writes:
This Rosettacode code task (in two different D versions) seems to 
show some D/Phobos regressions (or just some problems):

http://rosettacode.org/wiki/Parallel_calculations#D

In the second version (that works with dmd 2.066alpha) I have had 
to comment out the pure nothrow here, despite this used to 
compile few months ago:

     this(in ulong n) /*pure nothrow*/ {
         super(&run);
         num = n;
         fac = new ulong[0];
     }


The situation with the first version is worse. This is a 
compilable first version (at the moment the first version on the 
site doesn't have a decompose() function):


import std.stdio, std.algorithm, std.parallelism, std.typecons;

ulong[] decompose(ulong n) pure nothrow {
     typeof(return) result;
     for (ulong i = 2; n >= i * i; i++)
         for (; n % i == 0; n /= i)
             result ~= i;
     if (n != 1)
         result ~= n;
     return result;
}

void main() {
     immutable ulong[] data = [
         2UL^^59-1, 2UL^^59-1, 2UL^^59-1, 112_272_537_195_293UL,
         115_284_584_522_153, 115_280_098_190_773,
         115_797_840_077_099, 112_582_718_962_171,
         112_272_537_095_293, 1_099_726_829_285_419];

     //auto factors = taskPool.amap!(n => tuple(decompose(n), 
n))(data);
     //static enum genPair = (ulong n) pure => tuple(decompose(n), 
n); // ?
     static genPair(ulong n) pure { return tuple(decompose(n), n); 
}
     auto factors = taskPool.amap!genPair(data);

     auto pairs = factors.map!(p => tuple(p[0].reduce!min, p[1]));
     writeln("N. with largest min factor: ", pairs.reduce!max[1]);
}


A problem (that is not a regression) is that taskPool.amap 
doesn't seem able to accept a lambda for some reason.

It can't accept the static enum lambda either, for other unknown 
reasons.

But even using a normal static inner function, the program 
asserts most times at run-time (but not always), while few months 
ago it used to work reliably. So perhaps in this messy situation 
there's some material for bug reports. Opinions and suggestions 
are welcome.

Bye,
bearophile
Mar 18 2014
parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Wednesday, 19 March 2014 at 00:13:10 UTC, bearophile wrote:
 A problem (that is not a regression) is that taskPool.amap 
 doesn't seem able to accept a lambda for some reason.
The reason for that is that any function in D currently can have at most one context pointer. For class and struct methods, that is the "this" pointer. For free functions which take a lambda, such as "map", "reduce" and other std.algorithm functions, it is the context of the lambda (a pointer to the containing function's stack frame or whatnot). You can't have both. I think this is a glaring design problem in std.parallelism.
 But even using a normal static inner function, the program 
 asserts most times at run-time (but not always), while few 
 months ago it used to work reliably. So perhaps in this messy 
 situation there's some material for bug reports. Opinions and 
 suggestions are welcome.
Can you perform a regression test, or post the asserting program?
Mar 20 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Vladimir Panteleev:

 I think this is a glaring design problem in std.parallelism.
Do you want to report the issue in Bugzilla?
 Can you perform a regression test, or post the asserting 
 program?
It's the first program here (in the meantime I have updated it): http://rosettacode.org/wiki/Parallel_calculations#D Bye, bearophile
Mar 21 2014