-
Notifications
You must be signed in to change notification settings - Fork 11
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
Detect and throw an error when multithreading with Box
ed variables
#141
base: master
Are you sure you want to change the base?
Conversation
Okay, turns out we use a lot of boxed variables in the test suite. In particular with the @carstenbauer what do you think about this change? Is it too distruptive? We'd need to change things lke - x = 0
- y = 0
+ x = Ref(0)
+ y = Ref(0)
sao = SingleAccessOnly()
try
@tasks for i in 1:10
@set ntasks = 10
- y += 1 # not safe (race condition)
+ y[] += 1 # not safe (race condition)
@one_by_one begin
- x += 1 # parallel-safe because inside of one_by_one region
+ x[] += 1 # parallel-safe because inside of one_by_one region
acquire(sao) do
sleep(0.01)
end
end
end
- @test x == 10
+ @test x[] == 10
catch ErrorException
@test false
end |
Hm, telling the user to use Refs feels unfortunate to me. But so is having lots of boxed variables... |
Yeah :( |
Okay, so I went through and made all the tests pass. This actually was enough to convince me that this really is a good idea. You see, we did a lot of stuff like @testset "outer" begin
x = 0
@testset "inner" begin
@tasks for a in b
something_with(x)
end
end
test_func = () -> begin
x = 0
@tasks for a in b
something_else_with(x)
end
x
end
end Even that is enough to sneakily hit closure boxing because |
|
||
[deps] | ||
BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66" | ||
ChunkSplitters = "ae650224-84b6-46f8-82ea-d812ca08434e" | ||
ScopedValues = "7e506255-f358-4e82-b7e4-beb19740aa63" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed because we currently support the LTS v1.10, and ScopedValues were only added to Base
in v1.11
This can be removed if we ever drop v1.10
macro allow_boxed_captures(ex) | ||
quote | ||
@with allowing_boxed_captures => true $(esc(ex)) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to go with a scoped value here as the way to disable the error behaviour. This means that any outer-code can be simply annotated with
@allow_boxed_captures
and anything inside it will ignore the error checks. I think I like this design rather than using a kwarg per method of tmapreduce
/ tmap
/ @tasks
, etc. but I'm open to having my mind changed.
This also makes me wonder if some other stuff should be scoped values in the future 🤔
Closes #132, Closes #133
Before:
This PR:
This new behaviour can be opted out of with the new
@allow_boxed_captures
macro: