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

Mysterious inference failure that can be solved by redefining function #35537

Open
baggepinnen opened this issue Apr 21, 2020 · 3 comments
Open
Labels
compiler:inference Type inference

Comments

@baggepinnen
Copy link
Contributor

baggepinnen commented Apr 21, 2020

In a fresh julia session (v1.4.1), the following type inference test fails

x = [ones(3) for _ in 1:2]
s1(x) = x ./ sum(x)
testf(x) = s1.(x)
@inferred testf(x)

if

s1(x) = x ./ sum(x)
testf(x) = s1.(x)

are redefined, the test passes.
Output of REPL session below

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.4.1 (2020-04-14)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> x = [ones(3) for _ in 1:2]

2-element Array{Array{Float64,1},1}:
 [1.0, 1.0, 1.0]
 [1.0, 1.0, 1.0]

julia> s1(x) = x ./ sum(x)
s1 (generic function with 1 method)

julia> testf(x) = s1.(x)
testf (generic function with 1 method)

julia> @inferred testf(x)
ERROR: return type Array{Array{Float64,1},1} does not match inferred return type Any
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at none:0

julia> s1(x) = x ./ sum(x)
s1 (generic function with 1 method)

julia> testf(x) = s1.(x)
testf (generic function with 1 method)

julia> @inferred testf(x)
2-element Array{Array{Float64,1},1}:
 [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
 [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]

I think the problem lies in the broadcast machinery, if I replace

testf(x) = map(s1,x)

the problem goes away.
Cthulhu.jl points at Base.Broadcast.copy(%7::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}})::Any being the problem:

Body::Any
1 ─ %1 = Core.tuple(x)::Tuple{Array{Array{Float64,1},1}}
│   %2 = Base.arraysize(x, 1)::Int64
│   %3 = Base.slt_int(%2, 0)::Bool
│   %4 = Base.ifelse(%3, 0, %2)::Int64
│   %5 = %new(Base.OneTo{Int64}, %4)::Base.OneTo{Int64}
│   %6 = Core.tuple(%5)::Tuple{Base.OneTo{Int64}}
│   %7 = %new(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}}, s1, %1, %6)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}}
│   %8 = invoke Base.Broadcast.copy(%7::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}})::Any
└──      return %8
@Micket
Copy link
Contributor

Micket commented May 9, 2020

Ever so slightly reduced example

julia> f(x) = x * 2;
julia> g(x) = f.(x);
julia> @code_typed optimize=false g([[1.]]) # optimized or not, same return type
CodeInfo(
1%1 = Base.broadcasted(Main.f, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(f),Tuple{Array{Array{Float64,1},1}}}
│   %2 = Base.materialize(%1)::Union{BitArray{1}, Array}
└──      return %2
) => Union{BitArray{1}, Array}
julia> f(x) = x * 2;
julia> g(x) = f.(x);
julia> f([1.]) # trigger compilation of f first
julia> @code_typed optimize=false g([[1.]]) # optimizations just inlined everything
CodeInfo(
1%1 = Base.broadcasted(Main.f, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(f),Tuple{Array{Array{Float64,1},1}}}
│   %2 = Base.materialize(%1)::Array{Array{Float64,1},1}
└──      return %2
) => Array{Array{Float64,1},1}

@tkf
Copy link
Member

tkf commented May 9, 2020

Maybe related to #35800?

@aviatesk
Copy link
Member

The root problem for this is duplicated with #35800. Let's close this in favor of it.

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

4 participants