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

Bounds error in dynamo with dummy metadata #44

Open
phipsgabler opened this issue Jan 26, 2020 · 1 comment
Open

Bounds error in dynamo with dummy metadata #44

phipsgabler opened this issue Jan 26, 2020 · 1 comment

Comments

@phipsgabler
Copy link
Contributor

I know I shouldn't build IR from scratch, but I really wonder why the following happens:

julia> plus_dummy(x, y) = nothing
plus_dummy (generic function with 1 method)

julia> @dynamo function foo(X, Y)
           ir = IR(typeof(plus_dummy), X, Y)
           @show ir
           @show _args = IRTools.arguments(ir)
           s = push!(ir, xcall(:+, _args[end-1], _args[end]))
           @show ir
           return!(ir, s)
           @show ir
           return ir
       end

julia> foo(1, 2)
ir = 1: (%1, %2, %3)
  return :(Main.nothing)
_args = IRTools.arguments(ir) = Any[%1, %2, %3]
ir = 1: (%1, %2, %3)
  %4 = %2 + %3
  return :(Main.nothing)
ir = 1: (%1, %2, %3)
  %4 = %2 + %3
  return %4
ERROR: BoundsError: attempt to access (1, 2)
  at index [3]
Stacktrace:
 [1] foo(::Int64, ::Int64) at /home/philipp/.julia/packages/IRTools/Fl3dY/src/reflection/dynamo.jl:44
 [2] top-level scope at REPL[7]:1
@MikeInnes
Copy link
Member

The lowered code gives a good idea:

julia> @code_lowered foo(1, 2)
CodeInfo(
1 ─      Base.getfield(args, 1)
│   %2 = Base.getfield(args, 2)
│   %3 = Base.getfield(args, 3)
│   %4 = %2 + %3
└──      return %4
)

The IR for plus_dummy is expecting three arguments (itself, x and y) but the dynamo actually only takes two (X and Y). If you delete the self argument it works fine:

@dynamo function foo(X, Y)
  ir = IR(typeof(plus_dummy), X, Y)
  _args = IRTools.arguments(ir)
  deletearg!(block(ir, 1), 1)
  s = push!(ir, xcall(:+, _args[end-1], _args[end]))
  return!(ir, s)
  return ir
end

I know I shouldn't build IR from scratch

FWIW, I don't see any reason why we shouldn't support this well. I think I'd ideally write this as

@dynamo function foo(X, Y)
  ir = IR()
  args = argument!(ir)
  x = push!(ir, xcall(:getindex, args, 1))
  y = push!(ir, xcall(:getindex, args, 2))
  return!(ir, xcall(:+, x, y))
end

The only thing we need is (1) a standardised calling convention for IR without metadata (here I'm assuming that all args are passed in a single args tuple) and (2) some machinery to convert such IR to a codeinfo (which would look a lot like what you've done here, just inside the @dynamo).

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