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

type inference of tuple access across function boundary #21341

Closed
tehrengruber opened this issue Apr 10, 2017 · 9 comments
Closed

type inference of tuple access across function boundary #21341

tehrengruber opened this issue Apr 10, 2017 · 9 comments
Labels
compiler:inference Type inference

Comments

@tehrengruber
Copy link

tehrengruber commented Apr 10, 2017

Accessing the n-th field of a tuple via the [] operator is type stable in case n is a literal. However as soon as I wrap the access into a function, type inference fails even if I annotate the function with @inline.

@inline f(t::Tuple, i::Int) = t[i]
g1(t::Tuple) = link(t, 1)
g2(t::Tuple) = t[1]

t = (1, 2.)
julia> @code_warntype g1(t)
Variables:
  #self#::#g1
  t::Tuple{Int64,Float64}

Body:
  begin 
      return (Base.getfield)(t::Tuple{Int64,Float64}, 1)::Union{Float64, Int64}
  end::Union{Float64, Int64}
julia> @code_warntype g2(t)
Variables:
  #self#::#g2
  t::Tuple{Int64,Float64}

Body:
  begin 
      return (Base.getfield)(t::Tuple{Int64,Float64}, 1)::Int64
  end::Int64

Version:

Julia Version 0.6.0-dev.1393
Commit e19a8bf (2016-12-09 01:03 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz
  WORD_SIZE: 64
  BLAS: libopenblas (NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: liblapack.so.3
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1 (ORCJIT, haswell)

Note that this also occurs on a very recent master.

@marius311
Copy link
Contributor

I asked this identical question on the message boards, see some useful comments and basically the answer here. Essentially this doesn't and isn't supposed to currently work.

You can use Val types as a workaround if you need type stability. NamedTuples.jl might also work depending what you're trying to do.

@kshyatt kshyatt added the compiler:inference Type inference label Apr 14, 2017
@JeffBezanson
Copy link
Member

Related: #5560

Basically, it is difficult to do this efficiently since we can't analyze every function body for every constant value.

@JeffBezanson
Copy link
Member

More discussion of this in #17880

@JeffBezanson JeffBezanson changed the title Type inference for tuple fields type inference of tuple access across function boundary Apr 18, 2017
@tehrengruber
Copy link
Author

I see thanks for the links both of you. I think I have read all links carefully, but I think no one suggested the following (because the cases were different):
Before we do type inference we check every every function that is called for the number of methods it has. If it has only one method and is marked as inline we inline the call before type inference runs and add a type check (in case the signature does not match, which is not known at that time) that might be eliminated after inference (in the optimization step). This is somewhat similar to the idea of @andyferris in #17880, but without the problems that occurred there.

@vtjnash
Copy link
Member

vtjnash commented Apr 24, 2017

If it has only one method

This is only known after inference has finished. Indeed, it is exactly the job of inference to compute this.

@tehrengruber
Copy link
Author

Mh. First to be clear I mean "only one method" not "one applicable method". My reasoning was that before inference runs I already have access to all generic functions that are called (from a user perspective I should be able to call methods(f) during inference in the context of the current function on which inference runs. For simplicity I assume that f is not a closure). If that is this case I can just count the number of methods. Therefore I conclude from your answer that during type inference access to the generic functions is not possible, because otherwise my idea should work (unless I miss something else). The reason for this however is not clear to me. Do you mind to explain briefly?

@vtjnash
Copy link
Member

vtjnash commented Apr 24, 2017

Until you've run inference, you don't know what f is. It's possible that it's something easy, like a GlobalRef, but it's the job of inference to figure that out.

@tehrengruber
Copy link
Author

I see. Thanks for pointing this out.

@KristofferC
Copy link
Member

Closing as dup (or very similar) to #5560

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference
Projects
None yet
Development

No branches or pull requests

6 participants