On Tuesday, 4 April 2023 at 16:22:29 UTC, Steven Schveighoffer wrote:
> On 4/4/23 11:34 AM, Salih Dincer wrote:
> On Tuesday, 4 April 2023 at 14:20:20 UTC, Steven Schveighoffer wrote:
> parallel is a shortcut to TaskPool.parallel
, which is indeed a foreach-only construct, it does not return a range.
I think what you want is TaskPool.map
:
// untested, just looking at the
taskPool.map!(/* your map function here */)
(s.iota(len)).writeln;
I tried, thanks but it goes into infinite loop. For example, the first 50 of the sequence should have been printed to the screen immediately without waiting.
long[50] arr;
RowlandSequence_v2 range;
auto next(long a)
{
range.popFront();
return arr[a] = range.front();
}
void main()
{
range = RowlandSequence_v2(7, 2);
taskPool.map!next(iota(50))/*
s.iota(50)
.map!next
.parallel//*/
.writeln;
}
Keep in mind that arr
and range
are thread-local, and so will be different states for different tasks.
I guess the reason it goes into an infinite loop is because gcd() a recursive function (gcd). This is the only solution I can think of about this:
import std.range, std.algorithm : map;
import std.stdio, std.parallelism;
//import std.numeric : gcd;
/*
struct Vector {
long x, y, result;
alias result this;
}
Vector gcd(long a, long b) {
if(b == 0) return Vector(1, 0, a);
auto pre = gcd(b, a % b);
auto tmp = (a / b) * pre.y;
return Vector(pre.y, pre.x - tmp, pre.result);
}//*/
struct RowlandSequence_v3 {
long b, r, n, a = 3, limit;
bool empty() { return n == limit; }
auto front() { return a; }
void popFront() {
long result = 1;
while(result == 1) {
result = gcd(r++, b);
b += result;
}
a = result;
}
long gcd(long a, long b) {
long c;
while(b != 0) {
c = a % b;
a = b;
b = c;
}
return a;
}
}
auto next(ref RowlandSequence_v3 range) {
with(range) {
if(empty) return [n, front];
popFront();
return [n++, front];
}
}
long[179] arr;
void main()
{
// initialization:
RowlandSequence_v3[4] r = [
RowlandSequence_v3(7 , 2, 0, 3, 112),
RowlandSequence_v3(186837678, 62279227, 112, 3, 145),
RowlandSequence_v3(747404910, 249134971, 145, 6257, 160),
RowlandSequence_v3(1494812421, 498270808, 160, 11, 177)
];
auto tasks = [ task(&next, r[0]),
task(&next, r[1]),
task(&next, r[2]),
task(&next, r[3])
];
// quad parallel operation:
foreach(_; 0..r[0].limit)
{
foreach(p, ref task; tasks)
{
task.executeInNewThread;
auto t = task.workForce;
arr[t[0]] = t[1];
}
}
// prints...
foreach(x, n; arr) {
switch(x + 1) {
case 112, 145, 160:
n.writeln; break;
default:
n.write(", ");
}
}
} /* PRINTS:
user@debian:~/Documents$ dmd -O rowlandSequence.d -release
user@debian:~/Documents$ time ./rowlandSequence
5, 3, 11, 3, 23, 3, 47, 3, 5, 3, 101, 3, 7, 11, 3, 13, 233, 3, 467, 3, 5, 3, 941, 3, 7, 1889, 3, 3779, 3, 7559, 3, 13, 15131, 3, 53, 3, 7, 30323, 3, 60647, 3, 5, 3, 101, 3, 121403, 3, 242807, 3, 5, 3, 19, 7, 5, 3, 47, 3, 37, 5, 3, 17, 3, 199, 53, 3, 29, 3, 486041, 3, 7, 421, 23, 3, 972533, 3, 577, 7, 1945649, 3, 163, 7, 3891467, 3, 5, 3, 127, 443, 3, 31, 7783541, 3, 7, 15567089, 3, 19, 29, 3, 5323, 7, 5, 3, 31139561, 3, 41, 3, 5, 3, 62279171, 3, 7, 83, 3
29, 3, 1103, 3, 5, 3, 13, 7, 124559609, 3, 107, 3, 911, 3, 249120239, 3, 11, 3, 7, 61, 37, 179, 3, 31, 19051, 7, 3793, 23, 3, 5, 3, 6257, 3
3, 11, 3, 13, 5, 3, 739, 37, 5, 3, 498270791, 3, 19, 11, 3
3, 3, 5, 3, 996541661, 3, 7, 37, 5, 3, 67, 1993083437, 3, 5, 3, 83, 3, 3, 0,
real 7m54.093s
user 7m54.062s
sys 0m0.024s
*/
However, parallel processing for 4-digit sequence elements is not promising at least for the Rowland Sequence.
SDB@79