cstjean / TraceCalls.jl

A debugging and profiling tool for Julia
Other
46 stars 4 forks source link

Comparing traces #41

Open mkborregaard opened 7 years ago

mkborregaard commented 7 years ago

Is there any capability for comparing traces? Say if you run a function with different arguments and somewhere in the call chain it dispatches differently, you can compare the call chains. (Maybe this is really specific to my use, where I have a single function that does a lot of different things).

cstjean commented 7 years ago

No, not at the moment, but I've thought about implementing map(function, Trace1, Trace2). For your use case, you can perhaps check out and adapt the definition of compare-past-trace.

On Wednesday, August 23, 2017, Michael Krabbe Borregaard < notifications@github.com> wrote:

Is there any capability for comparing traces? Say if you run a function with different arguments and somewhere in the call chain it dispatches differently, you can compare the call chains. (Maybe this is really specific to my use, where I have a single function that does a lot of different things).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/cstjean/TraceCalls.jl/issues/41, or mute the thread https://github.com/notifications/unsubscribe-auth/AIOSuC5I0UA7HGaMfcCxlrsphVW5-peLks5sbHiigaJpZM4PAc_E .

mkborregaard commented 7 years ago

Nice, I'll check out compare-past-trace. Looking forward to see if you can get map(function, Trace1, Trace2) to work for traces where some branches differ.

cstjean commented 7 years ago

traces where some branches differ.

Hmmm, that should probably be an error for map.

Say if you run a function with different arguments and somewhere in the call chain it dispatches differently, you can compare the call chains.

Can you be more specific, or provide an example?

mkborregaard commented 7 years ago

Like:

module Test
foo(x) = 2bar(x)

function bar(x)
    if x>2
        baz(x)
    else
        qux(x)
    end
end

baz(x) = 3
qux(x) = 4

export foo
end

using TraceCalls

a = @trace Test foo(1)
b = @trace Test foo(3)

I was going to plot the graphs but it seems like the above code does not work unless Test is an installed package? Anyway, a and b share the foo call and the bar call, but are separated by the baz and quz call. I thought it could be nice to plot a combined trace, where foo and bar get one color, baz a second and cuz a third, to reveal the consequence on the trace tree by changing input parameters.

cstjean commented 7 years ago

I was going to plot the graphs but it seems like the above code does not work unless Test is an installed package?

The module needs to be in a file that's in the LOAD_PATH. I just improved the error message, thank you for the report. You can also use @traceable for interactively-defined code:

module Test
using TraceCalls
@traceable foo(x) = 2bar(x)

@traceable function bar(x)
    if x>2
        baz(x)
    else
        qux(x)
    end
end

@traceable baz(x) = 3
@traceable qux(x) = 4

export foo

end

using TraceCalls, Test

a = @trace foo(1)
b = @trace foo(3)

Anyway, a and b share the foo call and the bar call, but are separated by the baz and quz call. I thought it could be nice to plot a combined trace, where foo and bar get one color, baz a second and cuz a third, to reveal the consequence on the trace tree by changing input parameters.

That could be useful, but we need to think about the semantics of compare_trace(tr1, tr2). If foo(1) and foo(3) are comparable (we should recursively go through their called functions and compare those), then does that mean that map(sqrt, [1,2,3]) and map(length, ["hey", "there"]) are also comparable? If foo(1) calls bar(2) then sqrt(5), but foo(3) only calls sqrt(5), would we attempt to match the two sqrt(5) calls? What about the reversed calling order (foo(3) calls sqrt(5) then bar(2))?

Maybe it would be easier to write compare_call_trees on top of the functions you're defining.

mkborregaard commented 7 years ago

Maybe, yes. In my graphs so far, I've opted to make calls to the same function from different parts of the code separate vertices in the graph. I wanted to do it the other way first (align all sqrts), but that seems to work only great for call graphs (the non-directed ones) but become incredibly noisy for call trees (showing the order of calls).

Thanks for the heads up on @traceable!