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

Overdubbing not working when function called from within @threads for loop #176

Open
jwscook opened this issue Jul 13, 2020 · 2 comments
Open

Comments

@jwscook
Copy link

jwscook commented Jul 13, 2020

I've found that Cassette hasn't been able to overdub into loops parallelised with @threads. Below is my MWE, which shows how I've been using it. Interestingly it works with @spawn, so I will be able to find a workaround by @spawning and fetching the iterations of my loop instead of using @threads for.

using Cassette, Base.Threads, Test

original() = false
replacement() = true

Cassette.@context Ctx
Cassette.overdub(::Ctx, fn::typeof(original), args...) = replacement(args...)

const ctx = Ctx()

# sanity test
@test  Cassette.overdub(ctx, original)

# try it with @threads
function foo(testvalue)
  @threads for i in 1 # any number of iterations
   @test original() == testvalue
  end
end
foo(original()) # calling normally works
Cassette.overdub(ctx, foo, replacement()) # overdub doesn't work

# fetch appears to work - EDIT: no it doesn't
baz() = original()
task = Threads.@spawn Cassette.overdub(ctx, baz)
@test fetch(task)

The error I get is:

julia> Cassette.overdub(ctx, foo, replacement()) # overdub doesn't work
Test Failed at REPL[8]:4
  Expression: original() == testvalue
   Evaluated: false == true
ERROR: TaskFailedException:
There was an error during testing
Stacktrace:
 [1] call at /home/cookj/.julia/packages/Cassette/158rp/src/context.jl:456 [inlined]
 [2] fallback at /home/cookj/.julia/packages/Cassette/158rp/src/context.jl:454 [inlined]
 [3] overdub at /home/cookj/.julia/packages/Cassette/158rp/src/context.jl:280 [inlined]
 [4] wait at ./task.jl:267 [inlined]
 [5] threading_run at ./threadingconstructs.jl:34 [inlined]
 [6] overdub(::Cassette.Context{nametype(Ctx),Nothing,Nothing,Cassette.var"##PassType#256",Nothing,Nothing}, ::typeof(Base.Threads.threading_run), ::var"#102#threadsfor_fun#2"{Bool,Int64}) at /home/cookj/.julia/packages/Cassette/158rp/src/overdub.jl:0
 [7] macro expansion at ./threadingconstructs.jl:93 [inlined]
 [8] foo at ./REPL[8]:3 [inlined]
 [9] overdub(::Cassette.Context{nametype(Ctx),Nothing,Nothing,Cassette.var"##PassType#256",Nothing,Nothing}, ::typeof(foo), ::Bool) at /home/cookj/.julia/packages/Cassette/158rp/src/overdub.jl:0
 [10] top-level scope at REPL[10]:1

Is anyone able to shed any light on this?

Version info:

  • Version 1.5.0-beta1.0 (2020-05-28)
  • 7057c7e9] Cassette v0.3.3
@jwscook jwscook changed the title Problems with @threads Overdubbing not working when function called from within @threads for loop Jul 13, 2020
@jwscook
Copy link
Author

jwscook commented Jul 13, 2020

This is a more accurate @spawn version of the @threads test

using Cassette, Base.Threads, Test

original() = false
replacement() = true

Cassette.@context Ctx
Cassette.overdub(::Ctx, fn::typeof(original), args...) = replacement(args...)

const ctx = Ctx()


function bar(testvalue)
  d = Dict()
  for i in 1
    d[i] = Threads.@spawn original()
  end
  for i in keys(d)
    @test fetch(d[i]) == testvalue
  end
end

bar(original())
Cassette.overdub(ctx, bar, replacement())

which also fails:

julia> Cassette.overdub(ctx, bar, replacement())
Test Failed at REPL[20]:7
  Expression: fetch(d[i]) == testvalue
   Evaluated: false == true
ERROR: There was an error during testing

@vchuravy
Copy link
Member

This is probably #120

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

No branches or pull requests

2 participants