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

Making introspection macros work for broadcasting syntax (.) #28615

Closed
roberthoenig opened this issue Aug 12, 2018 · 7 comments · Fixed by #35522
Closed

Making introspection macros work for broadcasting syntax (.) #28615

roberthoenig opened this issue Aug 12, 2018 · 7 comments · Fixed by #35522
Labels
domain:broadcast Applying a function over a collection domain:error handling Handling of exceptions by Julia or the user

Comments

@roberthoenig
Copy link
Contributor

roberthoenig commented Aug 12, 2018

julia> versioninfo()
Julia Version 1.0.0
Commit 5d4eaca0c9 (2018-08-08 20:58 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, haswell)
Environment:
  JULIA_EDITOR = code

julia> @which abs.([1,2,3])
ERROR: no unique matching method found for the specified argument types
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] which(::Any, ::Any) at ./reflection.jl:922
 [3] top-level scope at none:0

julia> @code_lowered abs.([1,2,3])
0-element Array{Union{Nothing, CodeInfo},1}

In the code above I'd expect @which to return broadcast and @code_lowered to return whatever code that broadcast gets lowered to.

If the loop fusion magic behind the scenes turns out to be complicated to work with these macros, clearer error messages (or, in the case of @code_lowered, an error message), would be great as well.

@roberthoenig roberthoenig changed the title Make introspection macros work for the dot . operator. Making introspection macros work for the dot . operator. Aug 12, 2018
@tkoolen
Copy link
Contributor

tkoolen commented Aug 12, 2018

Ref: #25474.

@KristofferC
Copy link
Sponsor Member

A workaround is to wrap in another function:

julia> f() = abs.([1,2,3])
f (generic function with 1 method)

julia> @code_lowered f()
CodeInfo(
1 1 ─ %1 = Base.Broadcast.materialize                                                 │
  │   %2 = Base.Broadcast.broadcasted                                                 │
  │   %3 = (Base.vect)(1, 2, 3)                                                       │
  │   %4 = (%2)(Main.abs, %3)                                                         │
  │   %5 = (%1)(%4)                                                                   │
  └──      return %5                                                                  │
)

@roberthoenig
Copy link
Contributor Author

Yeah, that works for some macros like @code_*. Unfortunately it doesn't help for macros that give you information about the outermost method called, like @which:

julia> foo() = abs.([1,2,3])
foo (generic function with 2 methods)

julia> @which foo()
foo() in Main at REPL[76]:1

@KristofferC
Copy link
Sponsor Member

For broadcasting it is not completely clear what function should be shown due to e.g. fusing. In sin.(x .+ y) would you expect @which to show sin? It is a bit missleading since the function is executed is actually usually more something like (x, y) -> sin(x + y). I guess materialize could always be shown but that is a bit pointless.

@roberthoenig
Copy link
Contributor Author

roberthoenig commented Aug 13, 2018

I was encountering this error when I tried to dig into and understand the broadcasting mechanism, so in that case, showing the initial broadcast call would've been useful. Or the call to copy if that comes first, I'm still getting familiar with the broadcasting system.

@JeffBezanson JeffBezanson changed the title Making introspection macros work for the dot . operator. Making introspection macros work for broadcasting syntax (.) Sep 12, 2018
@mbauman
Copy link
Sponsor Member

mbauman commented Sep 12, 2018

I know this is an old thread, but the introspection you're after is Meta.@lower:

julia> Meta.@lower abs.([1,2,3])
:($(Expr(:thunk, CodeInfo(
 1%1 = (Base.getproperty)(Base.Broadcast, :materialize)                   │
 │   %2 = (Base.getproperty)(Base.Broadcast, :broadcasted)                   │
 │   %3 = (Base.vect)(1, 2, 3)                                               │
 │   %4 = (%2)(abs, %3)                                                      │
 │   %5 = (%1)(%4)                                                           │
 └──      return %5                                                          │
))))

That'll give you the breadcrumbs you wanted. Note that it's a complicated expansion — there are two function calls there (well three including vect for the [1,2,3] literal) — which do you want to introspect? If we just showed you Broadcast.materialize(bc::Base.Broadcast.Broadcasted) without giving you any more information about what it's argument was, it'd be similarly unhelpful.

I'm not sure we can really do much here. Perhaps the @which|@code_*|@edit macros could error and suggest Meta.@lower for expressions containing dots or other more complicated syntaxes.

@aminya
Copy link

aminya commented Apr 17, 2020

I get the same error for @code_llvm:

I have to wrap the broadcast calls inside a function. Calling the broadcast directly results in an error.

x=rand(10)
sinm(x) = sin.(x)

@code_llvm sinm(x)
@code_llvm sin.(x)

Error:

julia> @code_llvm sin.(x)
ERROR: no unique matching method found for the specified argument types
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] which(::Any, ::Any) at .\reflection.jl:1148
 [3] _dump_function(::Any, ::Any, ::Bool, ::Bool, ::Bool, ::Bool, ::Symbol, ::Bool, ::Symbol, ::Base.CodegenParams) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:77
 [4] _dump_function at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:71 [inlined]
 [5] code_llvm at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:132 [inlined]
 [6] #code_llvm#28 at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:134 [inlined]
 [7] code_llvm(::Any, ::Any; raw::Bool, dump_module::Bool, optimize::Bool, debuginfo::Symbol) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:136
 [8] code_llvm(::Any, ::Any) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\InteractiveUtils\src\codeview.jl:136
 [9] top-level scope at none:0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:broadcast Applying a function over a collection domain:error handling Handling of exceptions by Julia or the user
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants