Skip to content

Conversation

@IanButterworth
Copy link
Member

@IanButterworth IanButterworth commented Jul 16, 2025

Closes #209

See docstring for examples.

Developed with help from Claude.

@IanButterworth IanButterworth added the multithreading Base.Threads and related functionality label Jul 16, 2025
@IanButterworth IanButterworth added parallelism Parallel or distributed computation macros @macros labels Jul 16, 2025
@adienes
Copy link
Member

adienes commented Jul 16, 2025

the fact that this always returns a Vector{Any} is a bit rough

just some further cases that might want to be handled:

multiple loops

julia> @threads [i + j for i in 1:3, j in 1:3]
ERROR: TaskFailedException

non-indexable iterators

julia> @threads [i for i in Iterators.flatten(1:3)]
ERROR: TaskFailedException

@ericphanson
Copy link
Contributor

ericphanson commented Jul 17, 2025

it seems a little odd to me that :greedy does not preserve order. It seems mostly the different flavors change performance characteristics without changing semantics (or only changing semantics when you rely on details like threadids), but unordered is a pretty big semantic change.

Could it be called :unordered or :greedy_unordered or something to make it explicit? Or alternatively, could we just order it post-hoc by passing the index along?

(BTW: feels like there might be some similarity to Threads.foreach(f, c::Channel) from #34543 which I think is still not a well-known feature)

@IanButterworth
Copy link
Member Author

If Threads.foreach(f, c::Channel) could gain a filter kwarg, it might be worth just making this a wrapper for that?

@IanButterworth
Copy link
Member Author

IanButterworth commented Oct 5, 2025

@adienes I addressed your points in #59019 (comment)

@ericphanson I kept :greedy to match the existing @threads option. Not strongly attached, but it seems simplest to keep it the same.

Comment on lines +32 to +33
@test all(result_greedy[i] == i^2 for i in 1:n)
@test issorted(result_greedy) # should be ordered for greedy scheduling too
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two tests seem wrong. :greedy does not guarantee any particular execution order, so there is no reason it should be preserved. It's better to check that every element in the result is also present when the same kind of collection is done without threading:

Suggested change
@test all(result_greedy[i] == i^2 for i in 1:n)
@test issorted(result_greedy) # should be ordered for greedy scheduling too
result_nonthreaded = [ i^2 for i in 1:n ]
@test all(result_greedy) do r
r in result_nonthreaded
end

This is of course quadratic, but since :greedy doesn't guarantee an order, anything else runs into ordering problems.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But now we store i greedy has been made order-preserving via the sort at the end.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:greedy should not have to guarantee that though. The suggestion for adding the original index I gave on slack was for :static and :dynamic, which are order preserving by design.

Comment on lines +58 to +59
@test length(result_greedy) == length(expected)
@test result_greedy == expected # should preserve order
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, :greedy does not guarantee this.

Comment on lines +123 to +125
result_greedy = @threads :greedy [i * j for i in 1:3, j in 1:3]
@test size(result_greedy) == size(expected_static)
@test result_greedy == expected_static # greedy scheduling preserves order and dimensions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macros @macros multithreading Base.Threads and related functionality parallelism Parallel or distributed computation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add comprehension support to @threads

4 participants