Skip to content

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

@jwscook

Description

@jwscook

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions