Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vlib: add an arrays.parallel module, containing parallel.run/3 and parallel.amap/3 implementations #22090

Merged
merged 12 commits into from
Aug 24, 2024

Conversation

prashanth-hegde
Copy link
Contributor

arrays.run_parallel
arrays.map_parallel

Description

When we want to run functions on input array in parallel, a simple for loop does not suffice.
This implementation uses channels and waitgroups to let the user run a lambda function to run tasks in parallel.
It also allows the user to specify the max workers to achieve parallelism

@prashanth-hegde
Copy link
Contributor Author

Why is this failing on crypto/pem? I don't have any changes or dependencies on that.

@spytheman
Copy link
Member

spytheman commented Aug 22, 2024

Not sure about the exact reason (yet), but vlib/crypto/pem/encode.v does import arrays 🤔 .

@spytheman
Copy link
Member

spytheman commented Aug 22, 2024

Imho move the implementation in vlib/arrays/parallel/ .
Then users will be able to: import arrays.parallel, and parallel.map(...) + parallel.run(...).
The dependency problem for people that do not want all of sync, math and runtime, but still want to use the rest of arrays, will be also eliminated.

edit: I just tried it, and it works, but the map name will have to be renamed to something else, like amap, since map is parsed as a builtin type (the one that implements all maps).

It also solves the vlib/crypto/pem/pem_test.v failure (since the arrays module is not modified).
image

@prashanth-hegde
Copy link
Contributor Author

Imho move the implementation in vlib/arrays/parallel/

Good Idea, will do that

@prashanth-hegde
Copy link
Contributor Author

@spytheman thanks for the review. The review comments are good.
I have addressed your review comments. Please take a look when you can.

@spytheman
Copy link
Member

The windows tcc CI failure is unrelated to this PR. The other (the ubuntu musc one) is (it happens for the new test). Not sure why yet.

Prashanth.Hegde and others added 9 commits August 24, 2024 09:24
Co-authored-by: Delyan Angelov <delian66@gmail.com>
Per the code comments, moving the run and amap implementation to
arrays.parallel
Ensuring ordering in amap() implementation
Enhancing tests to not be module specific per code comments
Per the code comments, moving the run and amap implementation to
arrays.parallel
Ensuring ordering in amap() implementation
Enhancing tests to not be module specific per code comments
@spytheman
Copy link
Member

(rebased over current master, to pickup the windows CI fix, and add some changes to make it easier to diagnose the rest of the CI failures)

@spytheman
Copy link
Member

The macos failures happen very seldom locally (~20% of the time).
Here is one:

[vlib/arrays/parallel/parallel_test.v:20] input: [1, 2, 3, 4, 5, 6, 7, 8, 9]
[vlib/arrays/parallel/parallel_test.v:26] output: [1, 4, 9, 16, 36, 49, 64, 81]
vlib/arrays/parallel/parallel_test.v:29: ✗ fn test_parallel_amap
   > assert output[i] == input[i] * input[i]
     Left value: 36
    Right value: 25

The input has 9 elements, the output has 8 (the 25 for 5*5 is missing).
Perhaps there is a race somewhere.

…bility of the caller). Fix races (<< is not thread safe) on macos, cleanup and comment more
@spytheman spytheman changed the title run_parallel vlib: add an arrays.parallel module, containing parallel.run/3 and parallel.amap/3 implementations Aug 24, 2024
@spytheman
Copy link
Member

spytheman commented Aug 24, 2024

The race was for the a << e operations, done in the worker functions. Doing array pushes, is not thread safe: if 2 threads try to do them in a race, a will contain in the end only one of the new e elements, depending on which thread was last to update a.data.

Instead of using << in the workers, the fix (among other things), pre-allocates the result task array in amap, and then just does tasks_ref[task.idx] = t, which is safe to races (because each task is only processed by 1 worker thread).

@medvednikov
Copy link
Member

Would be nice to detect this in runtime in debug mode or with a separate flag.

@spytheman
Copy link
Member

Would be nice to detect this in runtime in debug mode or with a separate flag.

Yes, although I have no idea how will it work. V currently does not track what array is used by which threads.

@spytheman spytheman merged commit a31cd37 into vlang:master Aug 24, 2024
67 checks passed
@prashanth-hegde
Copy link
Contributor Author

Thank you! I was busy with work for a couple days. Appreciate the changes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants