www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Lockstep iteration in parallel: Error: cannot have parameter of type

reply kdevel <kdevel vogtner.de> writes:
```
import std.range;
import std.parallelism;

void vec_op (double [] outp, const double [] inp,
    double function (double) f)
{
    foreach (ref a, b; parallel (lockstep (outp, inp)))
       a = f (b);
}
```

Should this compile? dmd says

```
[...]/src/phobos/std/parallelism.d(4094): Error: cannot have 
parameter of type `void`
[...]/src/phobos/std/parallelism.d(4095): Error: cannot have 
parameter of type `void`
[...]/src/phobos/std/parallelism.d(3619): Error: template 
instance `std.parallelism.ParallelForeach!(Lockstep!(double[], 
const(double)[]))` error instantiating
lspar.d(7):        instantiated from here: 
`parallel!(Lockstep!(double[], const(double)[]))`
```
May 19 2023
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 5/19/23 02:17, kdevel wrote:

 Should this compile? dmd says
Multiple points: - lockstep works only with foreach loops but it's not a range. - std.range.zip can be used instead but it does not provide 'ref' access to its elements. - However, since slices are already references to groups of elements, you don't need 'ref' anyway. - You seem to want to assign to elements in parallel; such functionality already exists in std.parallelism. - Phobos documentation is not very useful these days as it's not clear from the following page that there are goodies like amap, asyncBuf, etc. It just shows parallel() and a few friends at the top: https://dlang.org/phobos/std_parallelism.html One needs to know to click TaskPool: https://dlang.org/phobos/std_parallelism.html#.TaskPool The following amap example there may be useful for your case but I could not make the types work: // Same thing, but explicitly allocate an array // to return the results in. The element type // of the array may be either the exact type // returned by functions or an implicit conversion // target. auto squareRoots = new float[numbers.length]; taskPool.amap!sqrt(numbers, squareRoots); // Multiple functions, explicit output range, and // explicit work unit size. auto results = new Tuple!(float, real)[numbers.length]; taskPool.amap!(sqrt, log)(numbers, 100, results); https://dlang.org/phobos/std_parallelism.html#.TaskPool.amap Ali
May 19 2023
parent reply kdevel <kdevel vogtner.de> writes:
Thanks for your explications!

On Friday, 19 May 2023 at 21:18:28 UTC, Ali Çehreli wrote:
 [...]
 - std.range.zip can be used instead but it does not provide 
 'ref' access to its elements.
How/why does sort [1] work with zipped arrays?
 [...]

 The following amap example there may be useful for your case 
 but I could not make the types work:
Do you mean using the function pointer does not work?
 // Same thing, but explicitly allocate an array
 // to return the results in.  The element type
 // of the array may be either the exact type
 // returned by functions or an implicit conversion
 // target.
 auto squareRoots = new float[numbers.length];
 taskPool.amap!sqrt(numbers, squareRoots);
This even seems to work with a static function pointer: int main () { import std.stdio; import std.math; import std.parallelism; const double [] a = [1., 2., 3., 4.]; double [] b = [0., 0., 0., 0.]; writeln (a); writeln (b); double function (double) fp = &sqrt; taskPool.amap!fp (a, b); writeln (a); writeln (b); return 0; } Using an automatic variable gives a deprecation warning main.amap!(const(double)[], double[]).amap` function requires a dual-context, which is deprecated [1] https://dlang.org/library/std/range/zip.html
May 20 2023
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 5/20/23 04:21, kdevel wrote:
 Thanks for your explications!

 On Friday, 19 May 2023 at 21:18:28 UTC, Ali Çehreli wrote:
 [...]
 - std.range.zip can be used instead but it does not provide 'ref'
 access to its elements.
How/why does sort [1] work with zipped arrays?
I don't know but wholesale assignment to zip's elements do transfer the effect, which sort does while swapping elements. However, copies of those range elements do not carry that effect: import std; void main() { auto a = [ 0, 1 ]; auto z = zip(a); z[0] = z[1]; writeln("worked: ", a); zip(a).each!(e => e = 42); writeln(" nope: ", a); } And each does not take (ref e) as a parameter at least in that use case.
 The following amap example there may be useful for your case but I
 could not make the types work:
Do you mean using the function pointer does not work?
I simply copied the example code bet there were mismatches between float, real, etc. And I've just discovered something. Which one of the following is the expected documentation? https://dlang.org/library/std/parallelism.html https://dlang.org/phobos/std_parallelism.html What paths did I take to get to those? I hope I will soon be motivated enough to fix such quality issues. Ali
May 20 2023
next sibling parent Sergey <kornburn yandex.ru> writes:
On Saturday, 20 May 2023 at 18:27:47 UTC, Ali Çehreli wrote:
 On 5/20/23 04:21, kdevel wrote:
 And I've just discovered something. Which one of the following 
 is the expected documentation?

   https://dlang.org/library/std/parallelism.html

   https://dlang.org/phobos/std_parallelism.html

 What paths did I take to get to those? I hope I will soon be 
 motivated enough to fix such quality issues.

 Ali
They both. Different versions of documentation generator afaik
May 20 2023
prev sibling parent kdevel <kdevel vogtner.de> writes:
On Saturday, 20 May 2023 at 18:27:47 UTC, Ali Çehreli wrote:
 [...]
 And I've just discovered something.
Me2! The serial version using array indexing void vec_op_naive0 (double [] outp, const double [] inp, double function (double) fp) { enforce (inp.length == outp.length); auto i = inp.length; while (i--) outp [i] = fp (inp [i]); } is nearly thrice as fast as the one using lockstep void vec_op (double [] outp, const double [] inp, double function (double) fp) { foreach (ref a, b; lockstep (outp, inp)) a = fp (b); } I wonder if under this circumstances (lack of speed, lack of parallelism out-of-the-box) it makes any sense to prefer lockstep over the indexed array access.
May 23 2023