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

Inference failure in negating a list of lists #49941

Closed
LilithHafner opened this issue May 23, 2023 · 4 comments
Closed

Inference failure in negating a list of lists #49941

LilithHafner opened this issue May 23, 2023 · 4 comments
Labels
compiler:inference Type inference feature Indicates new feature / enhancement requests

Comments

@LilithHafner
Copy link
Member

I feel like this should infer.

julia> Base.return_types(-, Tuple{Vector{Vector{Int64}}})
1-element Vector{Any}:
 Any

I ran into this because it caused dynamic dispatch that resulted in a performance bottleneck in some code I was writing. I'm switching to Vector{StaticArrays.SVector{2, Int64}} which does infer, so this is no longer an issue for me, but I'm still logging it because it seems odd and perhaps a place for inference to improve (if that wouldn't slow down inference time).

@LilithHafner LilithHafner added compiler:inference Type inference feature Indicates new feature / enhancement requests labels May 23, 2023
@nsajko
Copy link
Contributor

nsajko commented May 25, 2023

Minimal example:

julia> bvv = Base.broadcasted(-, [[1],[2]])
Base.Broadcast.Broadcasted(-, ([[1], [2]],))

julia> @inferred Base.materialize(bvv)
ERROR: return type Vector{Vector{Int64}} does not match inferred return type Any
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] top-level scope
   @ REPL[41]:1

julia> @code_warntype Base.materialize(bvv)
MethodInstance for Base.Broadcast.materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Vector{Vector{Int64}}}})
  from materialize(bc::Base.Broadcast.Broadcasted) @ Base.Broadcast broadcast.jl:903
Arguments
  #self#::Core.Const(Base.Broadcast.materialize)
  bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Vector{Vector{Int64}}}}
Body::Vector{Vector{Int64}}
1 ─      nothing
│   %2 = Base.Broadcast.instantiate(bc)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(-), Tuple{Vector{Vector{Int64}}}}
│   %3 = Base.Broadcast.copy(%2)::Vector{Vector{Int64}}
└──      return %3

How is it possible for @inferred to fail even though @code_warntype shows everything as correctly inferred?

@raminammour
Copy link
Contributor

Is there a reason why broadcast is specialized on the type of the function but broadcast_preserving_zero_d isn't?

broadcast(f::Tf, As...) where {Tf} = ...
@inline function broadcast_preserving_zero_d(f, As...) ...

Naively specializing in the REPL infers after hitting some form of #35800

julia> @eval Base.Broadcast @inline function broadcast_preserving_zero_d(f::F, As...) where F
           bc = broadcasted(f, As...)
           r = materialize(bc)
           return length(axes(bc)) == 0 ? fill!(similar(bc, typeof(r)), r) : r
       end
broadcast_preserving_zero_d (generic function with 5 methods)

julia> @eval Base.Broadcast Base.:-(A::AbstractArray) = @inline broadcast_preserving_zero_d(-, A)

julia> @code_warntype  -[[-1]]
MethodInstance for -(::Vector{Vector{Int64}})
  from -(A::AbstractArray) @ Base.Broadcast REPL[2]:1
Arguments
  #self#::Core.Const(-)
  A::Vector{Vector{Int64}}
Locals
  val::Any
Body::Any
1 ─     nothing
│       (val = Base.Broadcast.broadcast_preserving_zero_d(Base.Broadcast.:-, A))
│       nothing
└──     return val


julia> -[[1]]
1-element Vector{Vector{Int64}}:
 [-1]

julia> @code_warntype  -[[-1]]
MethodInstance for -(::Vector{Vector{Int64}})
  from -(A::AbstractArray) @ Base.Broadcast REPL[2]:1
Arguments
  #self#::Core.Const(-)
  A::Vector{Vector{Int64}}
Locals
  val::Any
Body::Any
1 ─     nothing
│       (val = Base.Broadcast.broadcast_preserving_zero_d(Base.Broadcast.:-, A))
│       nothing
└──     return val


julia> @eval Base.Broadcast Base.:-(A::AbstractArray) = @inline broadcast_preserving_zero_d(-, A)

julia> @code_warntype  -[[-1]]
MethodInstance for -(::Vector{Vector{Int64}})
  from -(A::AbstractArray) @ Base.Broadcast REPL[6]:1
Arguments
  #self#::Core.Const(-)
  A::Vector{Vector{Int64}}
Locals
  val::Vector{Vector{Int64}}
Body::Vector{Vector{Int64}}
1 ─     nothing
│       (val = Base.Broadcast.broadcast_preserving_zero_d(Base.Broadcast.:-, A))
│       nothing
└──     return val

So there may be a lot going on here :)

@adienes
Copy link
Contributor

adienes commented Apr 22, 2024

this (specific MWE given) does not reproduce on master

@LilithHafner
Copy link
Member Author

Great!

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

No branches or pull requests

4 participants