Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`
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.
Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`
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
Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`
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
Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`
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 = 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
Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`
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